0
0
Fork 0

まあ resolve #2 かな

This commit is contained in:
Xeltica 2020-09-08 22:10:21 +09:00
parent d20ac2c507
commit 41f40dd2c2
15 changed files with 100 additions and 40 deletions

View 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"');
}
}

View file

@ -1,6 +1,6 @@
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')));

View file

@ -1,4 +1,5 @@
import { initDb } from './services/db';
import 'reflect-metadata';
(async () => {
await initDb();

View 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;
};

View file

@ -1,15 +1,30 @@
import { User } from '../models/entities/user';
import { Users } from '../models';
import { DeepPartial } from 'typeorm';
import { genToken } from './gen-token';
export const getUser = (username: string, host: string): Promise<User | undefined> => {
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> => {
const u = await getUser(username, host);
if (u) {
await Users.update({ username, host }, { token });
await Users.update(u.id, { token });
} else {
await Users.insert({ username, host, token });
}

View 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;
}

View file

@ -21,6 +21,12 @@ export class User {
})
public token: string;
@Column({
type: 'varchar',
default: ''
})
public misshaiToken: string;
@Column({
type: 'integer',
default: 0,

View file

@ -1,4 +1,6 @@
import { User } from './entities/user';
import { UsedToken } from './entities/usedToken';
import { getRepository } from 'typeorm';
export const Users = getRepository(User);
export const UsedTokens = getRepository(UsedToken);

View file

View file

@ -3,7 +3,7 @@ import views from 'koa-views';
import constant from '../const';
export const render = views(__dirname + '/views', {
export const render = views(__dirname + '/../views', {
extension: 'pug', options: {
...constant,
}

View file

@ -6,22 +6,13 @@ import crypto from 'crypto';
import { die } from './die';
import { v4 as uuid } from 'uuid';
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';
export const router = new Router<DefaultState, Context>();
const sessionHostCache: 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 = [
'ついついノートしすぎていませんか?',
@ -32,16 +23,9 @@ const welcomeMessage = [
'あなたは真の Misskey 廃人ですか?'
];
const scoldingMessage = [
'さてはリロードを繰り返しているな?',
'何パターンあるか調べようとしてることはバレてんだぞ',
'何度もリロードして楽しいかい?',
'はいはいわかったから早うログインしな!',
'君には他にやるべきことがあるんじゃないか?',
];
const login = async (ctx: Context, user: Record<string, unknown>, host: string, token: string) => {
await upsertUser(user.username as string, host, token);
const u = await getUser(user.username as string, host);
if (!u) {
@ -55,21 +39,28 @@ const login = async (ctx: Context, user: Record<string, unknown>, host: string,
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 => {
const time = new Date().getTime();
freshIpAccessCount(time);
if (!ipAccessCount[ctx.ip]) {
ipAccessCount[ctx.ip] = { count: 0, time };
const token = ctx.cookies.get('token', { signed: true });
const user = token ? await getUserByMisshaiToken(token) : undefined;
if (!user) {
// 非ログイン
await ctx.render('welcome', {
usersCount: await getUserCount(),
welcomeMessage: welcomeMessage[Math.floor(Math.random() * welcomeMessage.length)],
});
} 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 => {

View file

@ -20,9 +20,11 @@ export default (): void => {
app.use(bodyParser());
app.use(render);
app.use(mount('/assets', serve(__dirname + '/assets')));
app.use(mount('/assets', serve(__dirname + '/../assets')));
app.use(router.routes());
app.keys = [ '人類', 'ミス廃化', '計画', 'ここに極まれり', 'フッフッフ...' ];
console.log(`listening port ${config.port}...`);
console.log('App launched!');

View file

@ -1,9 +1,11 @@
import { getConnection, createConnection, Connection } from 'typeorm';
import { config } from '../config';
import { User } from '../models/entities/user';
import { UsedToken } from '../models/entities/usedToken';
export const entities = [
User
User,
UsedToken,
];
export const initDb = async (force = false): Promise<Connection> => {

View file

@ -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
View file

@ -0,0 +1,6 @@
extends _base
block content
section
h2 マイページ
p おかえりなさい、@!{ user.username }@!{ user.host } さん。