Chg: 相対パス漏れをエイリアスに変更 / Fix: 各エンティティの全カラムにtypeを明示 / Feat: トークンの作成・使用時にログを記録 / Feat: Loggerでtypeの後の文字が整う機能
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { appendFileSync } from "node:fs";
|
||||
import { EOL } from "node:os";
|
||||
|
||||
const TYPE_MAX_LENGTH = 5;
|
||||
|
||||
const createLog = (
|
||||
nativeLogger: (...args: any[]) => void,
|
||||
type: string,
|
||||
@@ -11,7 +13,9 @@ const createLog = (
|
||||
args = args[0];
|
||||
}
|
||||
|
||||
const content = `${new Date().toLocaleString()} ${type} [${location}] ${args.join("\n").replaceAll("\n", "\n ")}`;
|
||||
const spacesForFlat = " ".repeat(TYPE_MAX_LENGTH - type.length);
|
||||
|
||||
const content = `${new Date().toLocaleString()} ${type}${spacesForFlat} [${location}] ${args.join("\n").replaceAll("\n", "\n ")}`;
|
||||
|
||||
nativeLogger(content);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Entity, EntityRepositoryType, PrimaryKey, Property } from "@mikro-orm/core";
|
||||
import { ConfigRepository } from "../repositories/Config";
|
||||
import { ConfigRepository } from "@/modules/repositories/Config";
|
||||
|
||||
@Entity({
|
||||
tableName: "config",
|
||||
|
||||
@@ -10,7 +10,10 @@ export class TokenEntity {
|
||||
[EntityRepositoryType]?: TokenRepository;
|
||||
[OptionalProps]?: "createdAt";
|
||||
|
||||
@PrimaryKey({ type: "string", length: 64 })
|
||||
@PrimaryKey({
|
||||
type: "string",
|
||||
length: 64,
|
||||
})
|
||||
name!: string;
|
||||
|
||||
@Property({ type: "text" })
|
||||
@@ -20,12 +23,18 @@ export class TokenEntity {
|
||||
@Index()
|
||||
user!: UserEntity;
|
||||
|
||||
@Property()
|
||||
@Property({ type: "boolean" })
|
||||
isNative!: boolean;
|
||||
|
||||
@Property({ onCreate: () => new Date() })
|
||||
@Property({
|
||||
type: "date",
|
||||
onCreate: () => new Date(),
|
||||
})
|
||||
createdAt!: Date;
|
||||
|
||||
@Property({ nullable: true })
|
||||
@Property({
|
||||
type: "date",
|
||||
nullable: true,
|
||||
})
|
||||
lastUsedAt?: Date;
|
||||
}
|
||||
|
||||
@@ -10,27 +10,50 @@ export class UserEntity {
|
||||
[EntityRepositoryType]?: UserRepository;
|
||||
[OptionalProps]?: "uuid" | "isSuspended" | "createdAt";
|
||||
|
||||
@PrimaryKey({ length: 36 })
|
||||
@PrimaryKey({
|
||||
type: "string",
|
||||
length: 36
|
||||
})
|
||||
uuid: string = uuid();
|
||||
|
||||
@Property({ unique: true, length: 20 })
|
||||
@Property({
|
||||
type: "string",
|
||||
unique: true,
|
||||
length: 20,
|
||||
})
|
||||
userid!: string;
|
||||
|
||||
@Property({ length: 30 })
|
||||
@Property({
|
||||
type: "string",
|
||||
length: 30,
|
||||
})
|
||||
username!: string;
|
||||
|
||||
@Property({ unique: true, length: 256 })
|
||||
@Property({
|
||||
type: "string",
|
||||
unique: true,
|
||||
length: 256,
|
||||
})
|
||||
email!: string;
|
||||
|
||||
@Property({ type: "text" })
|
||||
password!: string;
|
||||
|
||||
@Property({ default: false })
|
||||
@Property({
|
||||
type: "boolean",
|
||||
default: false,
|
||||
})
|
||||
isAdmin: boolean = false;
|
||||
|
||||
@Property({ default: false })
|
||||
@Property({
|
||||
type: "boolean",
|
||||
default: false,
|
||||
})
|
||||
isSuspended: boolean = false;
|
||||
|
||||
@Property({ onCreate: () => new Date() })
|
||||
@Property({
|
||||
type: "date",
|
||||
onCreate: () => new Date(),
|
||||
})
|
||||
createdAt!: Date;
|
||||
}
|
||||
@@ -4,11 +4,15 @@ import { hash, argon2id, verify as argon2Verify } from "argon2";
|
||||
import { randomBytes } from "node:crypto";
|
||||
import { UserEntity } from "@/modules/entities/User";
|
||||
import { ErrorBase } from "@/errors";
|
||||
import Logger from "@/lib/logger";
|
||||
|
||||
const logger = new Logger("Repo | Token.ts");
|
||||
|
||||
export class TokenRepository extends EntityRepository<TokenEntity> {
|
||||
async createToken(user: UserEntity, isNative: boolean) {
|
||||
const name = randomBytes(32).toString("hex");
|
||||
const passphrase = randomBytes(32).toString("hex");
|
||||
const TOKEN_BYTES = 32;
|
||||
const name = randomBytes(TOKEN_BYTES).toString("hex");
|
||||
const passphrase = randomBytes(TOKEN_BYTES).toString("hex");
|
||||
|
||||
const hashed = await hash(passphrase, {
|
||||
type: argon2id,
|
||||
@@ -25,6 +29,13 @@ export class TokenRepository extends EntityRepository<TokenEntity> {
|
||||
});
|
||||
|
||||
await this.em.persist(token).flush();
|
||||
logger.info(
|
||||
"Token created:",
|
||||
`User: @${user.userid}`,
|
||||
`Type: ${isNative
|
||||
? "Native"
|
||||
: "API Token"}`
|
||||
);
|
||||
|
||||
return `${name}_${passphrase}`;
|
||||
}
|
||||
@@ -60,8 +71,15 @@ export class TokenRepository extends EntityRepository<TokenEntity> {
|
||||
message: "トークンが不正です。",
|
||||
});
|
||||
|
||||
token.lastUsedAt = new Date()
|
||||
token.lastUsedAt = new Date();
|
||||
await this.em.persist(token).flush();
|
||||
logger.info(
|
||||
"Token used:",
|
||||
`User: @${token.user.userid}`,
|
||||
`Type: ${token.isNative
|
||||
? "Native"
|
||||
: "API Token"}`
|
||||
);
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user