fix: refactor forgot password system (#329)

* refactor forgot password system

* ready
This commit is contained in:
Philip Okugbe
2024-09-19 15:51:51 +01:00
committed by GitHub
parent b152c858b4
commit e56f7933f4
29 changed files with 578 additions and 338 deletions
+3 -3
View File
@@ -22,7 +22,7 @@ import { AttachmentRepo } from './repos/attachment/attachment.repo';
import { KyselyDB } from '@docmost/db/types/kysely.types';
import * as process from 'node:process';
import { MigrationService } from '@docmost/db/services/migration.service';
import { UserTokensRepo } from './repos/user-tokens/user-tokens.repo';
import { UserTokenRepo } from './repos/user-token/user-token.repo';
// https://github.com/brianc/node-postgres/issues/811
types.setTypeParser(types.builtins.INT8, (val) => Number(val));
@@ -67,7 +67,7 @@ types.setTypeParser(types.builtins.INT8, (val) => Number(val));
PageHistoryRepo,
CommentRepo,
AttachmentRepo,
UserTokensRepo,
UserTokenRepo,
],
exports: [
WorkspaceRepo,
@@ -80,7 +80,7 @@ types.setTypeParser(types.builtins.INT8, (val) => Number(val));
PageHistoryRepo,
CommentRepo,
AttachmentRepo,
UserTokensRepo,
UserTokenRepo,
],
})
export class DatabaseModule implements OnModuleDestroy, OnApplicationBootstrap {
@@ -7,13 +7,13 @@ export async function up(db: Kysely<any>): Promise<void> {
col.primaryKey().defaultTo(sql`gen_uuid_v7()`),
)
.addColumn('token', 'varchar', (col) => col.notNull())
.addColumn('type', 'varchar', (col) => col.notNull())
.addColumn('user_id', 'uuid', (col) =>
col.notNull().references('users.id').onDelete('cascade'),
)
.addColumn('workspace_id', 'uuid', (col) =>
col.references('workspaces.id').onDelete('cascade'),
)
.addColumn('type', 'varchar', (col) => col.notNull())
.addColumn('expires_at', 'timestamptz')
.addColumn('used_at', 'timestamptz', (col) => col)
.addColumn('created_at', 'timestamptz', (col) =>
@@ -1,6 +1,7 @@
import {
InsertableUserToken,
UpdatableUserToken,
UserToken,
} from '@docmost/db/types/entity.types';
import { KyselyDB, KyselyTransaction } from '@docmost/db/types/kysely.types';
import { dbOrTx } from '@docmost/db/utils';
@@ -8,9 +9,33 @@ import { Injectable } from '@nestjs/common';
import { InjectKysely } from 'nestjs-kysely';
@Injectable()
export class UserTokensRepo {
export class UserTokenRepo {
constructor(@InjectKysely() private readonly db: KyselyDB) {}
async findById(
token: string,
workspaceId: string,
trx?: KyselyTransaction,
): Promise<UserToken> {
const db = dbOrTx(this.db, trx);
return db
.selectFrom('userTokens')
.select([
'id',
'token',
'userId',
'workspaceId',
'type',
'expiresAt',
'usedAt',
'createdAt',
])
.where('token', '=', token)
.where('workspaceId', '=', workspaceId)
.executeTakeFirst();
}
async insertUserToken(
insertableUserToken: InsertableUserToken,
trx?: KyselyTransaction,
@@ -28,24 +53,24 @@ export class UserTokensRepo {
workspaceId: string,
tokenType: string,
trx?: KyselyTransaction,
) {
): Promise<UserToken[]> {
const db = dbOrTx(this.db, trx);
return db
.selectFrom('userTokens')
.select([
'id',
'token',
'user_id',
'workspace_id',
'userId',
'workspaceId',
'type',
'expires_at',
'used_at',
'created_at',
'expiresAt',
'usedAt',
'createdAt',
])
.where('user_id', '=', userId)
.where('workspace_id', '=', workspaceId)
.where('userId', '=', userId)
.where('workspaceId', '=', workspaceId)
.where('type', '=', tokenType)
.orderBy('expires_at desc')
.orderBy('expiresAt desc')
.execute();
}
@@ -57,33 +82,21 @@ export class UserTokensRepo {
const db = dbOrTx(this.db, trx);
return db
.updateTable('userTokens')
.set({ ...updatableUserToken })
.set(updatableUserToken)
.where('id', '=', userTokenId)
.execute();
}
async deleteUserToken(
userId: string,
workspaceId: string,
tokenType: string,
trx?: KyselyTransaction,
) {
async deleteToken(token: string, trx?: KyselyTransaction): Promise<void> {
const db = dbOrTx(this.db, trx);
return db
.deleteFrom('userTokens')
.where('user_id', '=', userId)
.where('workspace_id', '=', workspaceId)
.where('type', '=', tokenType)
.execute();
await db.deleteFrom('userTokens').where('token', '=', token).execute();
}
async deleteExpiredUserTokens(
trx?: KyselyTransaction,
) {
async deleteExpiredUserTokens(trx?: KyselyTransaction): Promise<void> {
const db = dbOrTx(this.db, trx);
return db
await db
.deleteFrom('userTokens')
.where('expires_at', '<', new Date())
.execute();
.where('expiresAt', '<', new Date())
.execute();
}
}
+23 -23
View File
@@ -1,22 +1,22 @@
import type { ColumnType } from 'kysely';
/**
* This file was generated by kysely-codegen.
* Please do not edit it manually.
*/
export type Generated<T> =
T extends ColumnType<infer S, infer I, infer U>
? ColumnType<S, I | undefined, U>
: ColumnType<T, T | undefined, T>;
import type { ColumnType } from "kysely";
export type Int8 = ColumnType<
string,
bigint | number | string,
bigint | number | string
>;
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U>
? ColumnType<S, I | undefined, U>
: ColumnType<T, T | undefined, T>;
export type Int8 = ColumnType<string, bigint | number | string, bigint | number | string>;
export type Json = JsonValue;
export type JsonArray = JsonValue[];
export type JsonObject = {
[K in string]?: JsonValue;
[x: string]: JsonValue | undefined;
};
export type JsonPrimitive = boolean | number | string | null;
@@ -162,6 +162,17 @@ export interface Users {
workspaceId: string | null;
}
export interface UserTokens {
createdAt: Generated<Timestamp>;
expiresAt: Timestamp | null;
id: Generated<string>;
token: string;
type: string;
usedAt: Timestamp | null;
userId: string;
workspaceId: string | null;
}
export interface WorkspaceInvitations {
createdAt: Generated<Timestamp>;
email: string | null;
@@ -190,17 +201,6 @@ export interface Workspaces {
updatedAt: Generated<Timestamp>;
}
export interface UserTokens {
id: Generated<string>;
token: string;
user_id: string;
workspace_id: string;
type: string;
expires_at: Timestamp | null;
used_at: Timestamp | null;
created_at: Generated<Timestamp>;
}
export interface DB {
attachments: Attachments;
comments: Comments;
@@ -211,7 +211,7 @@ export interface DB {
spaceMembers: SpaceMembers;
spaces: Spaces;
users: Users;
userTokens: UserTokens;
workspaceInvitations: WorkspaceInvitations;
workspaces: Workspaces;
userTokens: UserTokens;
}
@@ -73,7 +73,7 @@ export type Attachment = Selectable<Attachments>;
export type InsertableAttachment = Insertable<Attachments>;
export type UpdatableAttachment = Updateable<Omit<Attachments, 'id'>>;
// User Tokens
// User Token
export type UserToken = Selectable<UserTokens>;
export type InsertableUserToken = Insertable<UserTokens>;
export type UpdatableUserToken = Updateable<Omit<UserTokens, 'id'>>;