diff --git a/README.md b/README.md index f3b68947..c589efc7 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ You can configure the application using environment variables. Here are the avai | Environment Variable | Description | Default Value | | -------------------- | ----------- | ------------- | | `PORT` | The port to listen on when using node server | `8787` | -| `CORS_ORIGIN` | The CORS origin the server should allow | `*` | +| `SERVER_CORS_ORIGINS` | The CORS origin for the api server | _No default value_ | | `NOTES_MAX_ENCRYPTED_CONTENT_LENGTH` | The maximum length of the encrypted content of a note allowed by the api | `5242880` | | `TASK_DELETE_EXPIRED_NOTES_ENABLED` | Whether to enable a periodic task to delete expired notes (not available for cloudflare) | `true` | | `TASK_DELETE_EXPIRED_NOTES_CRON` | The frequency with which to run the task to delete expired notes (cron syntax) | `0 * * * *` | diff --git a/packages/app-server/package.json b/packages/app-server/package.json index 580c9f76..1ca6b7b2 100644 --- a/packages/app-server/package.json +++ b/packages/app-server/package.json @@ -20,13 +20,12 @@ "dev:cloudflare": "wrangler dev --test-scheduled --port=8787 src/index.cloudflare.ts", "build:cloudflare": "esbuild --bundle src/index.cloudflare.ts --format=esm --outfile=dist-cloudflare/_worker.js --minify", "build:node": "esbuild --bundle src/index.node.ts --platform=node --format=cjs --outfile=dist-node/index.cjs --minify", - "preview": "wrangler pages dev", - "deploy": "$npm_execpath run build && wrangler pages deploy", "lint": "eslint .", "lint:fix": "eslint --fix .", "test": "vitest run", "test:watch": "vitest watch", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "script:generate-config-table": "tsx -r dotenv/config src/scripts/generate-config-table.script.ts" }, "dependencies": { "@hono/node-server": "^1.12.1", diff --git a/packages/app-server/src/modules/app/config/config.ts b/packages/app-server/src/modules/app/config/config.ts index 445c7b64..3014858a 100644 --- a/packages/app-server/src/modules/app/config/config.ts +++ b/packages/app-server/src/modules/app/config/config.ts @@ -15,14 +15,14 @@ export const configDefinition = { default: 8787, env: 'PORT', }, - corsOrigin: { - doc: 'The CORS origin the server should allow', + corsOrigins: { + doc: 'The CORS origin for the api server', schema: z.union([ z.string(), z.array(z.string()), ]).transform(value => (typeof value === 'string' ? value.split(',') : value)), - default: '*', - env: 'CORS_ORIGIN', + default: [], + env: 'SERVER_CORS_ORIGINS', }, }, notes: { diff --git a/packages/app-server/src/modules/app/middlewares/cors.middleware.ts b/packages/app-server/src/modules/app/middlewares/cors.middleware.ts index 7db0950f..afd27964 100644 --- a/packages/app-server/src/modules/app/middlewares/cors.middleware.ts +++ b/packages/app-server/src/modules/app/middlewares/cors.middleware.ts @@ -1,15 +1,11 @@ import { cors } from 'hono/cors'; +import { createMiddleware } from 'hono/factory'; import type { Context } from '../server.types'; -export const corsMiddleware = cors({ - origin: (origin, context: Context) => { - const allowedOrigins = context.get('config').server.corsOrigin; +export const corsMiddleware = createMiddleware(async (context: Context, next) => { + const { server: { corsOrigins } } = context.get('config'); - if (allowedOrigins.length === 1 && allowedOrigins[0] === '*') { - return origin; - } + const corsHandler = cors({ origin: corsOrigins }); - return allowedOrigins.find(allowedOrigin => allowedOrigin === origin); - }, - credentials: true, + return corsHandler(context, next); }); diff --git a/packages/app-server/src/scripts/generate-config-table.script.ts b/packages/app-server/src/scripts/generate-config-table.script.ts index b686d82b..c03850cb 100644 --- a/packages/app-server/src/scripts/generate-config-table.script.ts +++ b/packages/app-server/src/scripts/generate-config-table.script.ts @@ -1,5 +1,5 @@ /* eslint-disable no-console */ -import _ from 'lodash-es'; +import { isArray, isEmpty, isNil } from 'lodash-es'; import type { ConfigDefinition, ConfigDefinitionElement } from 'figue'; import { fs } from 'zx'; import { configDefinition } from '../modules/app/config/config'; @@ -25,7 +25,8 @@ const configDetails = walk(configDefinition); const rows = configDetails .filter(({ path }) => path[0] !== 'env') .map(({ doc, default: defaultValue, env }) => { - const defaultValueString = _.isNil(defaultValue) ? 'No default value' : `\`${defaultValue}\``; + const isEmptyDefaultValue = isNil(defaultValue) || (isArray(defaultValue) && isEmpty(defaultValue)); + const defaultValueString = isEmptyDefaultValue ? '_No default value_' : `\`${defaultValue}\``; return `| \`${env}\` | ${doc} | ${defaultValueString} |`; });