From fdb2fdfe3f53e357fc70b4c887a6fc2b16fe9737 Mon Sep 17 00:00:00 2001 From: melvinchia3636 Date: Sun, 5 Oct 2025 12:09:16 +0800 Subject: [PATCH] refactor(scripts): update schema generation logic to adapt to new project structure Former-commit-id: e0345494d98e2a4f07601ad3f9db74ce4d55465f [formerly dfcbb2b70f9c685849b0d9902334f56cfa0dd303] [formerly e7107aef101ebe9720b1c9312aba5ec3976ff057 [formerly d848268dd6bbe95d792536073d3f7a49daf87b20]] Former-commit-id: eecb2c8c8f9b34fcb08dcc671477f991ff488f62 [formerly 9a670f559aa2ebfca6bdeed28077d59172f122ea] Former-commit-id: 544a60e83d23b531ba4597e37d8fb334ddacfea7 --- scripts/generateCollectionsSchemas.ts | 89 ++-- .../database/PBService/services/create.ts | 2 +- .../database/PBService/services/delete.ts | 2 +- .../PBService/services/getFirstListItem.ts | 2 +- .../PBService/services/getFullList.ts | 2 +- .../database/PBService/services/getList.ts | 2 +- .../database/PBService/services/getOne.ts | 2 +- .../database/PBService/services/update.ts | 2 +- server/src/core/functions/utils/checkDB.ts | 2 +- server/src/core/routes/core.routes.ts | 1 - server/src/core/schema.ts | 2 +- server/src/lib/apiKeys/routes/auth.ts | 4 +- server/src/lib/apiKeys/schema.ts | 96 ++--- server/src/lib/modules/index.ts | 43 -- server/src/lib/user/routes/personalization.ts | 6 +- server/src/lib/user/routes/settings.ts | 6 +- server/src/lib/user/routes/twoFA.ts | 4 +- server/src/lib/user/schema.ts | 386 +++++++++--------- server/src/lib/user/utils/auth.ts | 2 +- 19 files changed, 308 insertions(+), 347 deletions(-) delete mode 100644 server/src/lib/modules/index.ts diff --git a/scripts/generateCollectionsSchemas.ts b/scripts/generateCollectionsSchemas.ts index 94957a3da..60bc68ce6 100644 --- a/scripts/generateCollectionsSchemas.ts +++ b/scripts/generateCollectionsSchemas.ts @@ -1,7 +1,7 @@ import { LoggingService } from '@server/core/functions/logging/loggingService' import chalk from 'chalk' import dotenv from 'dotenv' -import fs from 'fs/promises' +import fs from 'fs' import _ from 'lodash' import path from 'path' import PocketBase, { type CollectionModel } from 'pocketbase' @@ -39,7 +39,10 @@ interface FieldTypeMapping { // Constants const PATHS = { ENV_FILE: path.resolve(__dirname, '../env/.env.local'), - MODULES_DIR: path.resolve(__dirname, '../server/src/lib'), + MODULES_DIRS: [ + path.resolve(__dirname, '../server/src/lib/**/schema.ts'), + path.resolve(__dirname, '../apps/**/server/schema.ts') + ], CORE_SCHEMA: path.resolve(__dirname, '../server/src/core/schema.ts') } as const @@ -154,22 +157,29 @@ async function buildModuleCollectionsMap( ): Promise { const moduleCollectionsMap: ModuleCollectionsMap = {} - let allModules: Array<{ name: string; isDirectory(): boolean }> + let allModules: string[] = [] try { - const moduleEntries = await fs.readdir(PATHS.MODULES_DIR, { - withFileTypes: true - }) - - allModules = moduleEntries.filter(entry => entry.isDirectory()) + allModules = PATHS.MODULES_DIRS.map(dir => fs.globSync(dir)) + .flat() + .map(entry => entry.split('/').slice(0, -1).join('/')) } catch (error) { LoggingService.error(`Failed to read modules directory: ${error}`) process.exit(1) } + console.log(allModules) + for (const collection of collections) { const matchingModule = allModules.find(module => - collection.name.startsWith(_.snakeCase(module.name)) + collection.name.startsWith( + _.snakeCase( + module + .replace(/\/server$/, '') + .split('/') + .pop() || '' + ) + ) ) if (!matchingModule) { @@ -179,10 +189,18 @@ async function buildModuleCollectionsMap( continue } - if (!moduleCollectionsMap[matchingModule.name]) { - moduleCollectionsMap[matchingModule.name] = [] + const moduleName = matchingModule + .replace(/\/server$/, '') + .split('/') + .pop() + + const key = `${matchingModule}|${moduleName}` + + if (!moduleCollectionsMap[key]) { + moduleCollectionsMap[key] = [] } - moduleCollectionsMap[matchingModule.name].push(collection) + + moduleCollectionsMap[key].push(collection) } const totalCollections = Object.values(moduleCollectionsMap).flat().length @@ -242,12 +260,20 @@ export default ${_.camelCase(moduleName)}Schemas } // Generate main schema content -function generateMainSchemaContent(moduleNames: string[]): string { - const imports = moduleNames - .map( - moduleName => - ` ${moduleName}: (await import('@lib/${moduleName === 'users' ? 'user' : _.camelCase(moduleName)}/schema')).default,` - ) +function generateMainSchemaContent(moduleDirs: string[]): string { + const imports = moduleDirs + .map(moduleDir => { + const [moduleDirPath, moduleDirName] = moduleDir.split('|') + + const targetPath = path.join( + '@lib/', + moduleDirName, + moduleDirPath.split(moduleDirName).pop() || '', + 'schema' + ) + + return ` ${_.snakeCase(moduleDirName)}: (await import('${targetPath}')).default,` + }) .join('\n') return `import flattenSchemas from '@functions/utils/flattenSchema' @@ -269,10 +295,15 @@ async function writeFormattedFile( ): Promise { try { const formattedContent = await prettier.format(content, { - parser: 'typescript' + parser: 'typescript', + semi: false, + singleQuote: true, + trailingComma: 'none', + arrowParens: 'avoid', + endOfLine: 'auto' }) - await fs.writeFile(filePath, formattedContent) + fs.writeFileSync(filePath, formattedContent) } catch (error) { LoggingService.error(`Failed to write file ${filePath}: ${error}`) throw error @@ -285,11 +316,11 @@ async function generateSchemas( ): Promise { const moduleSchemas: Record = {} - const moduleNames: string[] = [] + const moduleDirs: string[] = [] + + for (const [moduleDir, collections] of Object.entries(moduleCollectionsMap)) { + const [moduleDirPath, moduleDirName] = moduleDir.split('|') - for (const [moduleDirName, collections] of Object.entries( - moduleCollectionsMap - )) { if (!collections.length) { LoggingService.warn( `No collections found for module ${chalk.bold(moduleDirName)}` @@ -299,7 +330,7 @@ async function generateSchemas( const moduleName = collections[0].name.split('__')[0] - moduleNames.push(moduleName) + moduleDirs.push(moduleDir) const moduleSchemaContent = generateModuleSchemaContent( moduleName, @@ -309,11 +340,7 @@ async function generateSchemas( moduleSchemas[moduleDirName] = moduleSchemaContent // Write individual module schema file - const moduleSchemaPath = path.join( - PATHS.MODULES_DIR, - moduleDirName, - 'schema.ts' - ) + const moduleSchemaPath = path.join(moduleDirPath, 'schema.ts') await writeFormattedFile(moduleSchemaPath, moduleSchemaContent) @@ -322,7 +349,7 @@ async function generateSchemas( ) } - const mainSchemaContent = generateMainSchemaContent(moduleNames) + const mainSchemaContent = generateMainSchemaContent(moduleDirs) return { moduleSchemas, mainSchemaContent } } diff --git a/server/src/core/functions/database/PBService/services/create.ts b/server/src/core/functions/database/PBService/services/create.ts index a0088e555..78efe44e7 100644 --- a/server/src/core/functions/database/PBService/services/create.ts +++ b/server/src/core/functions/database/PBService/services/create.ts @@ -121,7 +121,7 @@ export class Create< } const result = await this._pb - .collection((this.collectionKey as string).replace(/^users__/, '')) + .collection((this.collectionKey as string).replace(/^user__/, '')) .create(this._data, { expand: this._expand, fields: this._fields, diff --git a/server/src/core/functions/database/PBService/services/delete.ts b/server/src/core/functions/database/PBService/services/delete.ts index 8d675c467..79682977d 100644 --- a/server/src/core/functions/database/PBService/services/delete.ts +++ b/server/src/core/functions/database/PBService/services/delete.ts @@ -55,7 +55,7 @@ export class Delete } const result = await this._pb - .collection((this.collectionKey as string).replace(/^users__/, '')) + .collection((this.collectionKey as string).replace(/^user__/, '')) .delete(this._recordId) LoggingService.debug( diff --git a/server/src/core/functions/database/PBService/services/getFirstListItem.ts b/server/src/core/functions/database/PBService/services/getFirstListItem.ts index c5af7a6a7..8f36a0b57 100644 --- a/server/src/core/functions/database/PBService/services/getFirstListItem.ts +++ b/server/src/core/functions/database/PBService/services/getFirstListItem.ts @@ -102,7 +102,7 @@ export class GetFirstListItem< : 'id != ""' // Default filter to ensure we get a valid response const result = await this._pb - .collection((this.collectionKey as string).replace(/^users__/, '')) + .collection((this.collectionKey as string).replace(/^user__/, '')) .getFirstListItem(filterString, { sort: this._sort, expand: this._expand, diff --git a/server/src/core/functions/database/PBService/services/getFullList.ts b/server/src/core/functions/database/PBService/services/getFullList.ts index f01adf7cd..83634ec32 100644 --- a/server/src/core/functions/database/PBService/services/getFullList.ts +++ b/server/src/core/functions/database/PBService/services/getFullList.ts @@ -140,7 +140,7 @@ export class GetFullList< : undefined const result = (await this._pb - .collection((this.collectionKey as string).replace(/^users__/, '')) + .collection((this.collectionKey as string).replace(/^user__/, '')) .getFullList({ filter: filterString, sort: this._sort, diff --git a/server/src/core/functions/database/PBService/services/getList.ts b/server/src/core/functions/database/PBService/services/getList.ts index 9ba6783b1..cae1c98ca 100644 --- a/server/src/core/functions/database/PBService/services/getList.ts +++ b/server/src/core/functions/database/PBService/services/getList.ts @@ -135,7 +135,7 @@ export class GetList< : undefined const result = (await this._pb - .collection((this.collectionKey as string).replace(/^users__/, '')) + .collection((this.collectionKey as string).replace(/^user__/, '')) .getList(this._page, this._perPage, { filter: filterString, sort: this._sort, diff --git a/server/src/core/functions/database/PBService/services/getOne.ts b/server/src/core/functions/database/PBService/services/getOne.ts index 506ea6026..97cfb15dd 100644 --- a/server/src/core/functions/database/PBService/services/getOne.ts +++ b/server/src/core/functions/database/PBService/services/getOne.ts @@ -114,7 +114,7 @@ export class GetOne< } const result = this._pb - .collection((this.collectionKey as string).replace(/^users__/, '')) + .collection((this.collectionKey as string).replace(/^user__/, '')) .getOne(this._itemId, { expand: this._expand, fields: this._fields diff --git a/server/src/core/functions/database/PBService/services/update.ts b/server/src/core/functions/database/PBService/services/update.ts index f53239357..e625374a7 100644 --- a/server/src/core/functions/database/PBService/services/update.ts +++ b/server/src/core/functions/database/PBService/services/update.ts @@ -147,7 +147,7 @@ export class Update< } const result = await this._pb - .collection((this.collectionKey as string).replace(/^users__/, '')) + .collection((this.collectionKey as string).replace(/^user__/, '')) .update(this._recordId, this._data, { expand: this._expand, fields: this._fields diff --git a/server/src/core/functions/utils/checkDB.ts b/server/src/core/functions/utils/checkDB.ts index 3a610e3ea..44401f6e2 100644 --- a/server/src/core/functions/utils/checkDB.ts +++ b/server/src/core/functions/utils/checkDB.ts @@ -96,7 +96,7 @@ export async function connectToPocketBase( * Handles special cases like users__users -> users */ function mapCollectionName(collectionName: string): string { - return collectionName === 'users__users' ? 'users' : collectionName + return collectionName === 'user__users' ? 'users' : collectionName } /** diff --git a/server/src/core/routes/core.routes.ts b/server/src/core/routes/core.routes.ts index f557a988e..c376f833e 100644 --- a/server/src/core/routes/core.routes.ts +++ b/server/src/core/routes/core.routes.ts @@ -117,7 +117,6 @@ const coreRoutes = forgeRouter({ apiKeys: (await import('../../lib/apiKeys')).default, pixabay: (await import('../../lib/pixabay')).default, locations: (await import('../../lib/locations')).default, - modules: (await import('../../lib/modules')).default, backups: (await import('../../lib/backups')).default, database: (await import('../../lib/database')).default, ping, diff --git a/server/src/core/schema.ts b/server/src/core/schema.ts index 5312a0281..e3ebed16b 100644 --- a/server/src/core/schema.ts +++ b/server/src/core/schema.ts @@ -1,7 +1,7 @@ import flattenSchemas from '@functions/utils/flattenSchema' export const SCHEMAS = { - users: (await import('@lib/user/schema')).default, + user: (await import('@lib/user/schema')).default, todo_list: (await import('@lib/todoList/server/schema')).default, code_time: (await import('@lib/codeTime/server/schema')).default, idea_box: (await import('@lib/ideaBox/server/schema')).default, diff --git a/server/src/lib/apiKeys/routes/auth.ts b/server/src/lib/apiKeys/routes/auth.ts index 41b91ea7e..cbfbd6151 100644 --- a/server/src/lib/apiKeys/routes/auth.ts +++ b/server/src/lib/apiKeys/routes/auth.ts @@ -28,7 +28,7 @@ const createOrUpdate = forgeController const id = pb.instance.authStore.record!.id await pb.update - .collection('users__users') + .collection('user__users') .id(id) .data({ APIKeysMasterPasswordHash @@ -49,7 +49,7 @@ const verify = forgeController const decryptedMaster = decrypt2(password, challenge) - const user = await pb.getOne.collection('users__users').id(id).execute() + const user = await pb.getOne.collection('user__users').id(id).execute() const { APIKeysMasterPasswordHash } = user diff --git a/server/src/lib/apiKeys/schema.ts b/server/src/lib/apiKeys/schema.ts index 2a12e330d..e79fdac82 100644 --- a/server/src/lib/apiKeys/schema.ts +++ b/server/src/lib/apiKeys/schema.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import z from 'zod' const apiKeysSchemas = { entries: { @@ -9,129 +9,129 @@ const apiKeysSchemas = { icon: z.string(), key: z.string(), created: z.string(), - updated: z.string(), + updated: z.string() }), raw: { - id: "zhm94t1hfoq97oa", + id: 'zhm94t1hfoq97oa', listRule: '@request.auth.id != ""', viewRule: '@request.auth.id != ""', createRule: '@request.auth.id != ""', updateRule: '@request.auth.id != ""', deleteRule: '@request.auth.id != ""', - name: "api_keys__entries", - type: "base", + name: 'api_keys__entries', + type: 'base', fields: [ { - autogeneratePattern: "[a-z0-9]{15}", + autogeneratePattern: '[a-z0-9]{15}', hidden: false, - id: "text3208210256", + id: 'text3208210256', max: 15, min: 15, - name: "id", - pattern: "^[a-z0-9]+$", + name: 'id', + pattern: '^[a-z0-9]+$', presentable: false, primaryKey: true, required: true, system: true, - type: "text", + type: 'text' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "4k7c8zdb", + id: '4k7c8zdb', max: 0, min: 0, - name: "keyId", - pattern: "", + name: 'keyId', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "tcnowiel", + id: 'tcnowiel', max: 0, min: 0, - name: "name", - pattern: "", + name: 'name', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "l1a35cql", + id: 'l1a35cql', max: 0, min: 0, - name: "description", - pattern: "", + name: 'description', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "vhho1bhf", + id: 'vhho1bhf', max: 0, min: 0, - name: "icon", - pattern: "", + name: 'icon', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "ddcugsw3", + id: 'ddcugsw3', max: 0, min: 0, - name: "key", - pattern: "", + name: 'key', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { hidden: false, - id: "autodate2990389176", - name: "created", + id: 'autodate2990389176', + name: 'created', onCreate: true, onUpdate: false, presentable: false, system: false, - type: "autodate", + type: 'autodate' }, { hidden: false, - id: "autodate3332085495", - name: "updated", + id: 'autodate3332085495', + name: 'updated', onCreate: true, onUpdate: true, presentable: false, system: false, - type: "autodate", - }, + type: 'autodate' + } ], indexes: [ - "CREATE UNIQUE INDEX `idx_V6OVTl5FtN` ON `api_keys__entries` (`keyId`)", + 'CREATE UNIQUE INDEX `idx_V6OVTl5FtN` ON `api_keys__entries` (`keyId`)' ], - system: false, - }, - }, -}; + system: false + } + } +} -export default apiKeysSchemas; +export default apiKeysSchemas diff --git a/server/src/lib/modules/index.ts b/server/src/lib/modules/index.ts deleted file mode 100644 index bd3119bb6..000000000 --- a/server/src/lib/modules/index.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { forgeController, forgeRouter } from '@functions/routes' -import { ClientError } from '@functions/routes/utils/response' -import z from 'zod' - -const toggle = forgeController - .mutation() - .description('Toggle a module on/off') - .input({ - query: z.object({ - id: z.string() - }) - }) - .callback(async ({ pb, query: { id } }) => { - const user = pb.instance.authStore.record - - if (!user) { - throw new ClientError('Unauthorized to toggle module') - } - - const modules = user.enabledModules || [] - - if (!modules.includes(id)) { - modules.push(id) - } else { - const index = modules.indexOf(id) - - if (index > -1) { - modules.splice(index, 1) - } - } - - await pb.update - .collection('users__users') - .id(user.id) - .data({ - enabledModules: modules - }) - .execute() - }) - -export default forgeRouter({ - toggle -}) diff --git a/server/src/lib/user/routes/personalization.ts b/server/src/lib/user/routes/personalization.ts index afd6b615d..8c15ba5b0 100644 --- a/server/src/lib/user/routes/personalization.ts +++ b/server/src/lib/user/routes/personalization.ts @@ -122,7 +122,7 @@ const updateBgImage = forgeController }) .callback(async ({ pb, media: { file } }) => { const newRecord = await pb.update - .collection('users__users') + .collection('user__users') .id(pb.instance.authStore.record!.id) .data({ ...(await getMedia('bgImage', file)), @@ -150,7 +150,7 @@ const deleteBgImage = forgeController .statusCode(204) .callback(({ pb }) => pb.update - .collection('users__users') + .collection('user__users') .id(pb.instance.authStore.record!.id) .data({ bgImage: null @@ -199,7 +199,7 @@ const updatePersonalization = forgeController } await pb.update - .collection('users__users') + .collection('user__users') .id(pb.instance.authStore.record!.id) .data(toBeUpdated) .execute() diff --git a/server/src/lib/user/routes/settings.ts b/server/src/lib/user/routes/settings.ts index b4beb5a47..53f916ecb 100644 --- a/server/src/lib/user/routes/settings.ts +++ b/server/src/lib/user/routes/settings.ts @@ -18,7 +18,7 @@ const updateAvatar = forgeController const { id } = pb.instance.authStore.record! const newRecord = await pb.update - .collection('users__users') + .collection('user__users') .id(id) .data(fileResult) .execute() @@ -35,7 +35,7 @@ const deleteAvatar = forgeController const { id } = pb.instance.authStore.record! await pb.update - .collection('users__users') + .collection('user__users') .id(id) .data({ avatar: '' @@ -84,7 +84,7 @@ const updateProfile = forgeController if (Object.keys(updateData).length > 0) { await pb.update - .collection('users__users') + .collection('user__users') .id(id) .data(updateData) .execute() diff --git a/server/src/lib/user/routes/twoFA.ts b/server/src/lib/user/routes/twoFA.ts index 1beeaa531..53ba4d3a1 100644 --- a/server/src/lib/user/routes/twoFA.ts +++ b/server/src/lib/user/routes/twoFA.ts @@ -144,7 +144,7 @@ const verifyAndEnable = forgeController } await pb.update - .collection('users__users') + .collection('user__users') .id(pb.instance.authStore.record!.id) .data({ twoFASecret: encrypt( @@ -169,7 +169,7 @@ const disable = forgeController } await pb.update - .collection('users__users') + .collection('user__users') .id(pb.instance.authStore.record!.id) .data({ twoFASecret: '' diff --git a/server/src/lib/user/schema.ts b/server/src/lib/user/schema.ts index 6b5afe636..22e7c21c9 100644 --- a/server/src/lib/user/schema.ts +++ b/server/src/lib/user/schema.ts @@ -1,4 +1,4 @@ -import { z } from "zod"; +import z from 'zod' const usersSchemas = { users: { @@ -12,15 +12,13 @@ const usersSchemas = { name: z.string(), avatar: z.string(), dateOfBirth: z.string(), - theme: z.enum(["system", "light", "dark"]), + theme: z.enum(['system', 'light', 'dark']), color: z.string(), bgTemp: z.string(), bgImage: z.string(), backdropFilters: z.any(), fontFamily: z.string(), - language: z.enum(["zh-CN", "en", "ms", "zh-TW", ""]), - moduleConfigs: z.any(), - enabledModules: z.any(), + language: z.enum(['zh-CN', 'en', 'ms', 'zh-TW', '']), dashboardLayout: z.any(), spotifyAccessToken: z.string(), spotifyRefreshToken: z.string(), @@ -31,487 +29,467 @@ const usersSchemas = { twoFASecret: z.string(), fontScale: z.number(), created: z.string(), - updated: z.string(), + updated: z.string() }), raw: { - id: "_pb_users_auth_", - listRule: "id = @request.auth.id", - viewRule: "id = @request.auth.id", - createRule: "", - updateRule: "id = @request.auth.id", + id: '_pb_users_auth_', + listRule: 'id = @request.auth.id', + viewRule: 'id = @request.auth.id', + createRule: '', + updateRule: 'id = @request.auth.id', deleteRule: null, - name: "users", - type: "auth", + name: 'users', + type: 'auth', fields: [ { - autogeneratePattern: "[a-z0-9]{15}", + autogeneratePattern: '[a-z0-9]{15}', hidden: false, - id: "text3208210256", + id: 'text3208210256', max: 15, min: 15, - name: "id", - pattern: "^[a-z0-9]+$", + name: 'id', + pattern: '^[a-z0-9]+$', presentable: false, primaryKey: true, required: true, system: true, - type: "text", + type: 'text' }, { cost: 10, hidden: true, - id: "password901924565", + id: 'password901924565', max: 0, min: 8, - name: "password", - pattern: "", + name: 'password', + pattern: '', presentable: false, required: true, system: true, - type: "password", + type: 'password' }, { - autogeneratePattern: "[a-zA-Z0-9_]{50}", + autogeneratePattern: '[a-zA-Z0-9_]{50}', hidden: true, - id: "text2504183744", + id: 'text2504183744', max: 60, min: 30, - name: "tokenKey", - pattern: "", + name: 'tokenKey', + pattern: '', presentable: false, primaryKey: false, required: true, system: true, - type: "text", + type: 'text' }, { exceptDomains: null, hidden: false, - id: "email3885137012", - name: "email", + id: 'email3885137012', + name: 'email', onlyDomains: null, presentable: false, required: false, system: true, - type: "email", + type: 'email' }, { hidden: false, - id: "bool1547992806", - name: "emailVisibility", + id: 'bool1547992806', + name: 'emailVisibility', presentable: false, required: false, system: true, - type: "bool", + type: 'bool' }, { hidden: false, - id: "bool256245529", - name: "verified", + id: 'bool256245529', + name: 'verified', presentable: false, required: false, system: true, - type: "bool", + type: 'bool' }, { - autogeneratePattern: "users[0-9]{6}", + autogeneratePattern: 'users[0-9]{6}', hidden: false, - id: "text4166911607", + id: 'text4166911607', max: 150, min: 3, - name: "username", - pattern: "^[\\w][\\w\\.\\-]*$", + name: 'username', + pattern: '^[\\w][\\w\\.\\-]*$', presentable: false, primaryKey: false, required: true, system: false, - type: "text", + type: 'text' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "users_name", + id: 'users_name', max: 0, min: 0, - name: "name", - pattern: "", + name: 'name', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { hidden: false, - id: "users_avatar", + id: 'users_avatar', maxSelect: 1, maxSize: 5242880, mimeTypes: [ - "image/jpeg", - "image/png", - "image/svg+xml", - "image/gif", - "image/webp", + 'image/jpeg', + 'image/png', + 'image/svg+xml', + 'image/gif', + 'image/webp' ], - name: "avatar", + name: 'avatar', presentable: false, protected: false, required: false, system: false, - thumbs: ["256x0"], - type: "file", + thumbs: ['256x0'], + type: 'file' }, { hidden: false, - id: "fsmwvydl", - max: "", - min: "", - name: "dateOfBirth", + id: 'fsmwvydl', + max: '', + min: '', + name: 'dateOfBirth', presentable: false, required: false, system: false, - type: "date", + type: 'date' }, { hidden: false, - id: "nppdhyft", + id: 'nppdhyft', maxSelect: 1, - name: "theme", + name: 'theme', presentable: false, required: true, system: false, - type: "select", - values: ["system", "light", "dark"], + type: 'select', + values: ['system', 'light', 'dark'] }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "1ik4v2wa", + id: '1ik4v2wa', max: 0, min: 0, - name: "color", - pattern: "", + name: 'color', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "d0lgczhi", + id: 'd0lgczhi', max: 0, min: 0, - name: "bgTemp", - pattern: "", + name: 'bgTemp', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { hidden: false, - id: "xjb7bo9y", + id: 'xjb7bo9y', maxSelect: 1, maxSize: 5242880000, mimeTypes: null, - name: "bgImage", + name: 'bgImage', presentable: false, protected: false, required: false, system: false, thumbs: null, - type: "file", + type: 'file' }, { hidden: false, - id: "apt6wrsc", + id: 'apt6wrsc', maxSize: 2000000, - name: "backdropFilters", + name: 'backdropFilters', presentable: false, required: false, system: false, - type: "json", + type: 'json' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "c34od4fd", + id: 'c34od4fd', max: 0, min: 0, - name: "fontFamily", - pattern: "", + name: 'fontFamily', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { hidden: false, - id: "bv7hnazi", + id: 'bv7hnazi', maxSelect: 1, - name: "language", + name: 'language', presentable: false, required: false, system: false, - type: "select", - values: ["zh-CN", "en", "ms", "zh-TW"], + type: 'select', + values: ['zh-CN', 'en', 'ms', 'zh-TW'] }, { hidden: false, - id: "wu4w5mks", + id: 'wjxwozyv', maxSize: 2000000, - name: "moduleConfigs", + name: 'dashboardLayout', presentable: false, required: false, system: false, - type: "json", + type: 'json' }, { + autogeneratePattern: '', hidden: false, - id: "a7qz6gsx", - maxSize: 2000000, - name: "enabledModules", - presentable: false, - required: false, - system: false, - type: "json", - }, - { - hidden: false, - id: "wjxwozyv", - maxSize: 2000000, - name: "dashboardLayout", - presentable: false, - required: false, - system: false, - type: "json", - }, - { - autogeneratePattern: "", - hidden: false, - id: "t4oem4rk", + id: 't4oem4rk', max: 0, min: 0, - name: "spotifyAccessToken", - pattern: "", + name: 'spotifyAccessToken', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "pmtavvft", + id: 'pmtavvft', max: 0, min: 0, - name: "spotifyRefreshToken", - pattern: "", + name: 'spotifyRefreshToken', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { hidden: false, - id: "n6afyo6x", - max: "", - min: "", - name: "spotifyTokenExpires", + id: 'n6afyo6x', + max: '', + min: '', + name: 'spotifyTokenExpires', presentable: false, required: false, system: false, - type: "date", + type: 'date' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "ivwqhyvx", + id: 'ivwqhyvx', max: 0, min: 0, - name: "masterPasswordHash", - pattern: "", + name: 'masterPasswordHash', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "bva2tmvh", + id: 'bva2tmvh', max: 0, min: 0, - name: "journalMasterPasswordHash", - pattern: "", + name: 'journalMasterPasswordHash', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "afbxzben", + id: 'afbxzben', max: 0, min: 0, - name: "APIKeysMasterPasswordHash", - pattern: "", + name: 'APIKeysMasterPasswordHash', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { - autogeneratePattern: "", + autogeneratePattern: '', hidden: false, - id: "oi6j9b9d", + id: 'oi6j9b9d', max: 0, min: 0, - name: "twoFASecret", - pattern: "", + name: 'twoFASecret', + pattern: '', presentable: false, primaryKey: false, required: false, system: false, - type: "text", + type: 'text' }, { hidden: false, - id: "number3058924606", + id: 'number3058924606', max: null, min: 0.1, - name: "fontScale", + name: 'fontScale', onlyInt: false, presentable: false, required: true, system: false, - type: "number", + type: 'number' }, { hidden: false, - id: "autodate2990389176", - name: "created", + id: 'autodate2990389176', + name: 'created', onCreate: true, onUpdate: false, presentable: false, system: false, - type: "autodate", + type: 'autodate' }, { hidden: false, - id: "autodate3332085495", - name: "updated", + id: 'autodate3332085495', + name: 'updated', onCreate: true, onUpdate: true, presentable: false, system: false, - type: "autodate", - }, + type: 'autodate' + } ], indexes: [ - "CREATE UNIQUE INDEX `__pb_users_auth__username_idx` ON `users` (username COLLATE NOCASE)", + 'CREATE UNIQUE INDEX `__pb_users_auth__username_idx` ON `users` (username COLLATE NOCASE)', "CREATE UNIQUE INDEX `__pb_users_auth__email_idx` ON `users` (`email`) WHERE `email` != ''", - "CREATE UNIQUE INDEX `__pb_users_auth__tokenKey_idx` ON `users` (`tokenKey`)", + 'CREATE UNIQUE INDEX `__pb_users_auth__tokenKey_idx` ON `users` (`tokenKey`)' ], system: false, - authRule: "verified=true", + authRule: 'verified=true', manageRule: null, authAlert: { enabled: true, emailTemplate: { - subject: "Login from a new location", - body: "

Hello,

\n

We noticed a login to your {APP_NAME} account from a new location.

\n

If this was you, you may disregard this email.

\n

If this wasn't you, you should immediately change your {APP_NAME} account password to revoke access from all other locations.

\n

\n Thanks,
\n {APP_NAME} team\n

", - }, + subject: 'Login from a new location', + body: "

Hello,

\n

We noticed a login to your {APP_NAME} account from a new location.

\n

If this was you, you may disregard this email.

\n

If this wasn't you, you should immediately change your {APP_NAME} account password to revoke access from all other locations.

\n

\n Thanks,
\n {APP_NAME} team\n

" + } }, oauth2: { providers: [ { pkce: null, - name: "github", - clientId: "3ffe0179e120fd734d1c", - authURL: "", - tokenURL: "", - userInfoURL: "", - displayName: "", - extra: null, + name: 'github', + clientId: '3ffe0179e120fd734d1c', + authURL: '', + tokenURL: '', + userInfoURL: '', + displayName: '', + extra: null }, { pkce: null, - name: "google", + name: 'google', clientId: - "667707161573-3t64t2s6g5qr6rve19qibkmr6fbiq9f7.apps.googleusercontent.com", - authURL: "", - tokenURL: "", - userInfoURL: "", - displayName: "", - extra: null, - }, + '667707161573-3t64t2s6g5qr6rve19qibkmr6fbiq9f7.apps.googleusercontent.com', + authURL: '', + tokenURL: '', + userInfoURL: '', + displayName: '', + extra: null + } ], mappedFields: { - id: "username", - name: "name", - username: "name", - avatarURL: "avatar", + id: 'username', + name: 'name', + username: 'name', + avatarURL: 'avatar' }, - enabled: true, + enabled: true }, passwordAuth: { enabled: true, - identityFields: ["email", "username"], + identityFields: ['email', 'username'] }, mfa: { enabled: false, duration: 1800, - rule: "", + rule: '' }, otp: { enabled: true, duration: 180, length: 6, emailTemplate: { - subject: "OTP for {APP_NAME}", - body: "

Hello,

\n

Your one-time password is: {OTP}

\n

If you didn't ask for the one-time password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

", - }, + subject: 'OTP for {APP_NAME}', + body: "

Hello,

\n

Your one-time password is: {OTP}

\n

If you didn't ask for the one-time password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

" + } }, authToken: { - duration: 1209600, + duration: 1209600 }, passwordResetToken: { - duration: 1800, + duration: 1800 }, emailChangeToken: { - duration: 1800, + duration: 1800 }, verificationToken: { - duration: 604800, + duration: 604800 }, fileToken: { - duration: 120, + duration: 120 }, verificationTemplate: { - subject: "Verify your {APP_NAME} email", - body: '

Hello,

\n

Thank you for joining us at {APP_NAME}.

\n

Click on the button below to verify your email address.

\n

\n Verify\n

\n

\n Thanks,
\n {APP_NAME} team\n

', + subject: 'Verify your {APP_NAME} email', + body: '

Hello,

\n

Thank you for joining us at {APP_NAME}.

\n

Click on the button below to verify your email address.

\n

\n Verify\n

\n

\n Thanks,
\n {APP_NAME} team\n

' }, resetPasswordTemplate: { - subject: "Reset your {APP_NAME} password", - body: '

Hello,

\n

Click on the button below to reset your password.

\n

\n Reset password\n

\n

If you didn\'t ask to reset your password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

', + subject: 'Reset your {APP_NAME} password', + body: '

Hello,

\n

Click on the button below to reset your password.

\n

\n Reset password\n

\n

If you didn\'t ask to reset your password, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

' }, confirmEmailChangeTemplate: { - subject: "Confirm your {APP_NAME} new email address", - body: '

Hello,

\n

Click on the button below to confirm your new email address.

\n

\n Confirm new email\n

\n

If you didn\'t ask to change your email address, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

', - }, - }, - }, -}; + subject: 'Confirm your {APP_NAME} new email address', + body: '

Hello,

\n

Click on the button below to confirm your new email address.

\n

\n Confirm new email\n

\n

If you didn\'t ask to change your email address, you can ignore this email.

\n

\n Thanks,
\n {APP_NAME} team\n

' + } + } + } +} -export default usersSchemas; +export default usersSchemas diff --git a/server/src/lib/user/utils/auth.ts b/server/src/lib/user/utils/auth.ts index f8e39b46f..27b76109e 100644 --- a/server/src/lib/user/utils/auth.ts +++ b/server/src/lib/user/utils/auth.ts @@ -22,7 +22,7 @@ export function removeSensitiveData(userData: Record) { return newUserData as SchemaWithPB< Omit< - z.infer<(typeof COLLECTION_SCHEMAS)['users__users']>, + z.infer<(typeof COLLECTION_SCHEMAS)['user__users']>, | 'masterPasswordHash' | 'journalMasterPasswordHash' | 'APIKeysMasterPasswordHash'