diff --git a/docs/developing-server.md b/docs/developing-server.md index db67e7cb84..9f58a4af46 100644 --- a/docs/developing-server.md +++ b/docs/developing-server.md @@ -61,14 +61,13 @@ MAILER_USER="auth" MAILER_PASSWORD="auth" MAILER_HOST="localhost" MAILER_PORT="1025" -STRIPE_API_KEY=sk_live_1 -STRIPE_WEBHOOK_KEY=1 ``` ## Prepare prisma ``` yarn workspace @affine/server prisma db push +yarn workspace @affine/server data-migration run ``` Note, you may need to do it again if db schema changed. diff --git a/packages/backend/server/src/config/affine.self.ts b/packages/backend/server/src/config/affine.self.ts index 157ee2360c..cecc33fbbc 100644 --- a/packages/backend/server/src/config/affine.self.ts +++ b/packages/backend/server/src/config/affine.self.ts @@ -39,7 +39,15 @@ if (env.R2_OBJECT_STORAGE_ACCOUNT_ID) { } AFFiNE.plugins.use('redis'); -AFFiNE.plugins.use('payment'); +AFFiNE.plugins.use('payment', { + stripe: { + keys: { + // fake the key to ensure the server generate full GraphQL Schema even env vars are not set + APIKey: '1', + webhookKey: '1', + }, + }, +}); AFFiNE.plugins.use('oauth'); if (AFFiNE.deploy) { diff --git a/packages/backend/server/src/config/affine.ts b/packages/backend/server/src/config/affine.ts index 84b82036f7..1c22b3e88d 100644 --- a/packages/backend/server/src/config/affine.ts +++ b/packages/backend/server/src/config/affine.ts @@ -52,6 +52,18 @@ AFFiNE.port = 3010; // /* The metrics will be available at `http://localhost:9464/metrics` with [Prometheus] format exported */ // AFFiNE.metrics.enabled = true; // +// /* Authentication Settings */ +// /* User Signup password limitation */ +// AFFiNE.auth.password = { +// minLength: 8, +// maxLength: 20, +// }; +// +// /* How long the login session would last by default */ +// AFFiNE.auth.session = { +// ttl: 15 * 24 * 60 * 60, // 15 days +// }; +// // /* GraphQL configurations that control the behavior of the Apollo Server behind */ // /* @see https://www.apollographql.com/docs/apollo-server/api/apollo-server */ // AFFiNE.graphql = { @@ -84,15 +96,15 @@ AFFiNE.port = 3010; // /* Redis Plugin */ // /* Provide caching and session storing backed by Redis. */ // /* Useful when you deploy AFFiNE server in a cluster. */ -AFFiNE.plugins.use('redis', { - /* override options */ -}); +// AFFiNE.plugins.use('redis', { +// /* override options */ +// }); // // // /* Payment Plugin */ -AFFiNE.plugins.use('payment', { - stripe: { keys: {}, apiVersion: '2023-10-16' }, -}); +// AFFiNE.plugins.use('payment', { +// stripe: { keys: {}, apiVersion: '2023-10-16' }, +// }); // // // /* Cloudflare R2 Plugin */ diff --git a/packages/backend/server/src/core/utils/validators.ts b/packages/backend/server/src/core/utils/validators.ts index 547ae8a1e3..3621bd9b7d 100644 --- a/packages/backend/server/src/core/utils/validators.ts +++ b/packages/backend/server/src/core/utils/validators.ts @@ -5,12 +5,13 @@ function getAuthCredentialValidator() { const email = z.string().email({ message: 'Invalid email address' }); let password = z.string(); - const minPasswordLength = AFFiNE.node.prod ? 8 : 1; password = password - .min(minPasswordLength, { - message: `Password must be ${minPasswordLength} or more charactors long`, + .min(AFFiNE.auth.password.minLength, { + message: `Password must be ${AFFiNE.auth.password.minLength} or more charactors long`, }) - .max(20, { message: 'Password must be 20 or fewer charactors long' }); + .max(AFFiNE.auth.password.maxLength, { + message: `Password must be ${AFFiNE.auth.password.maxLength} or fewer charactors long`, + }); return z .object({ diff --git a/packages/backend/server/src/data/index.ts b/packages/backend/server/src/data/index.ts index 2d2f324f52..75f1828c82 100644 --- a/packages/backend/server/src/data/index.ts +++ b/packages/backend/server/src/data/index.ts @@ -3,9 +3,8 @@ import '../prelude'; import { Logger } from '@nestjs/common'; import { CommandFactory } from 'nest-commander'; -import { CliAppModule } from './app'; - async function bootstrap() { + const { CliAppModule } = await import('./app'); await CommandFactory.run(CliAppModule, new Logger()).catch(e => { console.error(e); process.exit(1); diff --git a/packages/backend/server/src/fundamentals/config/def.ts b/packages/backend/server/src/fundamentals/config/def.ts index a81d53be75..9c8825610f 100644 --- a/packages/backend/server/src/fundamentals/config/def.ts +++ b/packages/backend/server/src/fundamentals/config/def.ts @@ -220,6 +220,20 @@ export interface AFFiNEConfig { * authentication config */ auth: { + password: { + /** + * The minimum and maximum length of the password when registering new users + * + * @default 8 + */ + minLength: number; + /** + * The maximum length of the password + * + * @default 20 + */ + maxLength: number; + }; session: { /** * Application auth expiration time in seconds diff --git a/packages/backend/server/src/fundamentals/config/default.ts b/packages/backend/server/src/fundamentals/config/default.ts index f41bc16e7c..7cb4e938a3 100644 --- a/packages/backend/server/src/fundamentals/config/default.ts +++ b/packages/backend/server/src/fundamentals/config/default.ts @@ -77,7 +77,16 @@ export const getDefaultAFFiNEConfig: () => AFFiNEConfig = () => { Object.values(DeploymentType) ); const isSelfhosted = deploymentType === DeploymentType.Selfhosted; - + const affine = { + canary: AFFINE_ENV === 'dev', + beta: AFFINE_ENV === 'beta', + stable: AFFINE_ENV === 'production', + }; + const node = { + prod: NODE_ENV === 'production', + dev: NODE_ENV === 'development', + test: NODE_ENV === 'test', + }; const defaultConfig = { serverId: 'affine-nestjs-server', serverName: isSelfhosted ? 'Self-Host Cloud' : 'AFFiNE Cloud', @@ -98,19 +107,11 @@ export const getDefaultAFFiNEConfig: () => AFFiNEConfig = () => { ENV_MAP: {}, AFFINE_ENV, get affine() { - return { - canary: AFFINE_ENV === 'dev', - beta: AFFINE_ENV === 'beta', - stable: AFFINE_ENV === 'production', - }; + return affine; }, NODE_ENV, get node() { - return { - prod: NODE_ENV === 'production', - dev: NODE_ENV === 'development', - test: NODE_ENV === 'test', - }; + return node; }, get deploy() { return !this.node.dev && !this.node.test; @@ -150,6 +151,10 @@ export const getDefaultAFFiNEConfig: () => AFFiNEConfig = () => { playground: true, }, auth: { + password: { + minLength: node.prod ? 8 : 1, + maxLength: 32, + }, session: { ttl: 15 * ONE_DAY_IN_SEC, },