まあ resolve #2 かな
This commit is contained in:
parent
d20ac2c507
commit
41f40dd2c2
15 changed files with 100 additions and 40 deletions
18
migration/1599570288522-mypage.ts
Normal file
18
migration/1599570288522-mypage.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import {MigrationInterface, QueryRunner} from 'typeorm';
|
||||||
|
|
||||||
|
export class mypage1599570288522 implements MigrationInterface {
|
||||||
|
name = 'mypage1599570288522'
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query('CREATE TABLE "used_token" ("token" character varying NOT NULL, CONSTRAINT "PK_7f2db4c33c33cd6b38e63393fe5" PRIMARY KEY ("token"))');
|
||||||
|
await queryRunner.query('CREATE UNIQUE INDEX "IDX_7f2db4c33c33cd6b38e63393fe" ON "used_token" ("token") ');
|
||||||
|
await queryRunner.query('ALTER TABLE "user" ADD "misshaiToken" character varying NOT NULL DEFAULT \'\'');
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query('ALTER TABLE "user" DROP COLUMN "misshaiToken"');
|
||||||
|
await queryRunner.query('DROP INDEX "IDX_7f2db4c33c33cd6b38e63393fe"');
|
||||||
|
await queryRunner.query('DROP TABLE "used_token"');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
|
||||||
const entities = require('./built/db').entities;
|
const entities = require('./built/services/db').entities;
|
||||||
|
|
||||||
const config = Object.freeze(JSON.parse(fs.readFileSync(__dirname + '/config.json', 'utf-8')));
|
const config = Object.freeze(JSON.parse(fs.readFileSync(__dirname + '/config.json', 'utf-8')));
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { initDb } from './services/db';
|
import { initDb } from './services/db';
|
||||||
|
import 'reflect-metadata';
|
||||||
|
|
||||||
(async () => {
|
(async () => {
|
||||||
await initDb();
|
await initDb();
|
||||||
|
|
13
src/functions/gen-token.ts
Normal file
13
src/functions/gen-token.ts
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
import rndstr from 'rndstr';
|
||||||
|
import { UsedToken } from '../models/entities/usedToken';
|
||||||
|
import { UsedTokens } from '../models';
|
||||||
|
|
||||||
|
export const genToken = async (): Promise<string> => {
|
||||||
|
let used: UsedToken | undefined = undefined;
|
||||||
|
let token: string;
|
||||||
|
do {
|
||||||
|
token = rndstr(32);
|
||||||
|
used = await UsedTokens.findOne({ token });
|
||||||
|
} while (used !== undefined);
|
||||||
|
return token;
|
||||||
|
};
|
|
@ -1,15 +1,30 @@
|
||||||
import { User } from '../models/entities/user';
|
import { User } from '../models/entities/user';
|
||||||
import { Users } from '../models';
|
import { Users } from '../models';
|
||||||
import { DeepPartial } from 'typeorm';
|
import { DeepPartial } from 'typeorm';
|
||||||
|
import { genToken } from './gen-token';
|
||||||
|
|
||||||
export const getUser = (username: string, host: string): Promise<User | undefined> => {
|
export const getUser = (username: string, host: string): Promise<User | undefined> => {
|
||||||
return Users.findOne({ username, host });
|
return Users.findOne({ username, host });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const updateUsersMisshaiToken = async (user: User | User['id']): Promise<string> => {
|
||||||
|
const u = typeof user === 'number'
|
||||||
|
? user
|
||||||
|
: user.id;
|
||||||
|
|
||||||
|
const misshaiToken = await genToken();
|
||||||
|
Users.update(u, { misshaiToken });
|
||||||
|
return misshaiToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getUserByMisshaiToken = (token: string): Promise<User | undefined> => {
|
||||||
|
return Users.findOne({ misshaiToken: token });
|
||||||
|
};
|
||||||
|
|
||||||
export const upsertUser = async (username: string, host: string, token: string): Promise<void> => {
|
export const upsertUser = async (username: string, host: string, token: string): Promise<void> => {
|
||||||
const u = await getUser(username, host);
|
const u = await getUser(username, host);
|
||||||
if (u) {
|
if (u) {
|
||||||
await Users.update({ username, host }, { token });
|
await Users.update(u.id, { token });
|
||||||
} else {
|
} else {
|
||||||
await Users.insert({ username, host, token });
|
await Users.insert({ username, host, token });
|
||||||
}
|
}
|
||||||
|
|
10
src/models/entities/usedToken.ts
Normal file
10
src/models/entities/usedToken.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { Entity, Index, PrimaryColumn } from 'typeorm';
|
||||||
|
|
||||||
|
@Entity()
|
||||||
|
@Index([ 'token' ], { unique: true })
|
||||||
|
export class UsedToken {
|
||||||
|
@PrimaryColumn({
|
||||||
|
type: 'varchar'
|
||||||
|
})
|
||||||
|
public token: string;
|
||||||
|
}
|
|
@ -21,6 +21,12 @@ export class User {
|
||||||
})
|
})
|
||||||
public token: string;
|
public token: string;
|
||||||
|
|
||||||
|
@Column({
|
||||||
|
type: 'varchar',
|
||||||
|
default: ''
|
||||||
|
})
|
||||||
|
public misshaiToken: string;
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
type: 'integer',
|
type: 'integer',
|
||||||
default: 0,
|
default: 0,
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
import { User } from './entities/user';
|
import { User } from './entities/user';
|
||||||
|
import { UsedToken } from './entities/usedToken';
|
||||||
import { getRepository } from 'typeorm';
|
import { getRepository } from 'typeorm';
|
||||||
|
|
||||||
export const Users = getRepository(User);
|
export const Users = getRepository(User);
|
||||||
|
export const UsedTokens = getRepository(UsedToken);
|
0
src/models/repositories/.gitkeep
Normal file
0
src/models/repositories/.gitkeep
Normal file
|
@ -3,7 +3,7 @@ import views from 'koa-views';
|
||||||
|
|
||||||
import constant from '../const';
|
import constant from '../const';
|
||||||
|
|
||||||
export const render = views(__dirname + '/views', {
|
export const render = views(__dirname + '/../views', {
|
||||||
extension: 'pug', options: {
|
extension: 'pug', options: {
|
||||||
...constant,
|
...constant,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,22 +6,13 @@ import crypto from 'crypto';
|
||||||
import { die } from './die';
|
import { die } from './die';
|
||||||
import { v4 as uuid } from 'uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import { config } from '../config';
|
import { config } from '../config';
|
||||||
import { upsertUser, getUser, getUserCount, updateUser } from '../functions/users';
|
import { upsertUser, getUser, getUserCount, updateUser, updateUsersMisshaiToken, getUserByMisshaiToken } from '../functions/users';
|
||||||
import { api } from '../services/misskey';
|
import { api } from '../services/misskey';
|
||||||
|
|
||||||
export const router = new Router<DefaultState, Context>();
|
export const router = new Router<DefaultState, Context>();
|
||||||
|
|
||||||
const sessionHostCache: Record<string, string> = { };
|
const sessionHostCache: Record<string, string> = { };
|
||||||
const tokenSecretCache: Record<string, string> = { };
|
const tokenSecretCache: Record<string, string> = { };
|
||||||
const ipAccessCount: Record<string, { time: number, count: number }> = {};
|
|
||||||
|
|
||||||
const freshIpAccessCount = (time: number) => {
|
|
||||||
for (const ips of Object.keys(ipAccessCount)) {
|
|
||||||
if (time - ipAccessCount[ips].time > 2000) {
|
|
||||||
delete ipAccessCount[ips];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const welcomeMessage = [
|
const welcomeMessage = [
|
||||||
'ついついノートしすぎていませんか?',
|
'ついついノートしすぎていませんか?',
|
||||||
|
@ -32,16 +23,9 @@ const welcomeMessage = [
|
||||||
'あなたは真の Misskey 廃人ですか?'
|
'あなたは真の Misskey 廃人ですか?'
|
||||||
];
|
];
|
||||||
|
|
||||||
const scoldingMessage = [
|
|
||||||
'さてはリロードを繰り返しているな?',
|
|
||||||
'何パターンあるか調べようとしてることはバレてんだぞ',
|
|
||||||
'何度もリロードして楽しいかい?',
|
|
||||||
'はいはいわかったから早うログインしな!',
|
|
||||||
'君には他にやるべきことがあるんじゃないか?',
|
|
||||||
];
|
|
||||||
|
|
||||||
const login = async (ctx: Context, user: Record<string, unknown>, host: string, token: string) => {
|
const login = async (ctx: Context, user: Record<string, unknown>, host: string, token: string) => {
|
||||||
await upsertUser(user.username as string, host, token);
|
await upsertUser(user.username as string, host, token);
|
||||||
|
|
||||||
const u = await getUser(user.username as string, host);
|
const u = await getUser(user.username as string, host);
|
||||||
|
|
||||||
if (!u) {
|
if (!u) {
|
||||||
|
@ -55,21 +39,28 @@ const login = async (ctx: Context, user: Record<string, unknown>, host: string,
|
||||||
prevFollowersCount: user.followersCount as number,
|
prevFollowersCount: user.followersCount as number,
|
||||||
});
|
});
|
||||||
|
|
||||||
await ctx.render('logined', { user: u });
|
const misshaiToken = await updateUsersMisshaiToken(u);
|
||||||
|
|
||||||
|
ctx.cookies.set('token', misshaiToken, { signed: true });
|
||||||
|
|
||||||
|
// await ctx.render('logined', { user: u });
|
||||||
|
ctx.redirect('/');
|
||||||
};
|
};
|
||||||
|
|
||||||
router.get('/', async ctx => {
|
router.get('/', async ctx => {
|
||||||
const time = new Date().getTime();
|
const token = ctx.cookies.get('token', { signed: true });
|
||||||
freshIpAccessCount(time);
|
const user = token ? await getUserByMisshaiToken(token) : undefined;
|
||||||
if (!ipAccessCount[ctx.ip]) {
|
if (!user) {
|
||||||
ipAccessCount[ctx.ip] = { count: 0, time };
|
// 非ログイン
|
||||||
|
await ctx.render('welcome', {
|
||||||
|
usersCount: await getUserCount(),
|
||||||
|
welcomeMessage: welcomeMessage[Math.floor(Math.random() * welcomeMessage.length)],
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
ipAccessCount[ctx.ip] = { count: ipAccessCount[ctx.ip].count + 1, time };
|
await ctx.render('mypage', {
|
||||||
|
user
|
||||||
|
});
|
||||||
}
|
}
|
||||||
await ctx.render('welcome', {
|
|
||||||
usersCount: await getUserCount(),
|
|
||||||
welcomeMessage: ipAccessCount[ctx.ip].count > 5 ? scoldingMessage[Math.floor(Math.random() * scoldingMessage.length)] : welcomeMessage[Math.floor(Math.random() * welcomeMessage.length)],
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/login', async ctx => {
|
router.get('/login', async ctx => {
|
||||||
|
|
|
@ -20,9 +20,11 @@ export default (): void => {
|
||||||
|
|
||||||
app.use(bodyParser());
|
app.use(bodyParser());
|
||||||
app.use(render);
|
app.use(render);
|
||||||
app.use(mount('/assets', serve(__dirname + '/assets')));
|
app.use(mount('/assets', serve(__dirname + '/../assets')));
|
||||||
app.use(router.routes());
|
app.use(router.routes());
|
||||||
|
|
||||||
|
app.keys = [ '人類', 'ミス廃化', '計画', 'ここに極まれり', 'フッフッフ...' ];
|
||||||
|
|
||||||
console.log(`listening port ${config.port}...`);
|
console.log(`listening port ${config.port}...`);
|
||||||
console.log('App launched!');
|
console.log('App launched!');
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import { getConnection, createConnection, Connection } from 'typeorm';
|
import { getConnection, createConnection, Connection } from 'typeorm';
|
||||||
import { config } from '../config';
|
import { config } from '../config';
|
||||||
import { User } from '../models/entities/user';
|
import { User } from '../models/entities/user';
|
||||||
|
import { UsedToken } from '../models/entities/usedToken';
|
||||||
|
|
||||||
export const entities = [
|
export const entities = [
|
||||||
User
|
User,
|
||||||
|
UsedToken,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const initDb = async (force = false): Promise<Connection> => {
|
export const initDb = async (force = false): Promise<Connection> => {
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
extends _base
|
|
||||||
|
|
||||||
block content
|
|
||||||
section
|
|
||||||
h2 おかえりなさい、@!{ user.username }@!{ user.host } さん。
|
|
||||||
p みす廃あらーとの設定は完了しています。Have a good Misskey 👍
|
|
6
src/views/mypage.pug
Normal file
6
src/views/mypage.pug
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
extends _base
|
||||||
|
|
||||||
|
block content
|
||||||
|
section
|
||||||
|
h2 マイページ
|
||||||
|
p おかえりなさい、@!{ user.username }@!{ user.host } さん。
|
Loading…
Add table
Add a link
Reference in a new issue