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