diff --git a/deploy/deployment.yaml b/deploy/deployment.yaml index 665d2ad..63bd4f6 100644 --- a/deploy/deployment.yaml +++ b/deploy/deployment.yaml @@ -21,6 +21,8 @@ spec: value: '4' - name: SERVER_FORCE_SSL value: 'true' + - name: ENABLE_CORS + value: 'true' - name: DATABASE_USERNAME valueFrom: secretKeyRef: diff --git a/package.json b/package.json index 9b4fbdd..e252ada 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ }, "dependencies": { "@atao60/fse-cli": "^0.1.7", - "@extollo/lib": "^0.14.8", + "@extollo/lib": "^0.14.10", "@types/node": "^18.11.9", "any-date-parser": "^1.5.3", "copyfiles": "^2.4.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ada7591..ec5850f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,7 +3,7 @@ lockfileVersion: 5.4 specifiers: '@atao60/fse-cli': ^0.1.7 '@extollo/cc': ^0.6.0 - '@extollo/lib': ^0.14.8 + '@extollo/lib': ^0.14.10 '@types/node': ^18.11.9 any-date-parser: ^1.5.3 copyfiles: ^2.4.1 @@ -19,7 +19,7 @@ specifiers: dependencies: '@atao60/fse-cli': 0.1.7 - '@extollo/lib': 0.14.8 + '@extollo/lib': 0.14.10 '@types/node': 18.11.9 any-date-parser: 1.5.3 copyfiles: 2.4.1 @@ -126,8 +126,8 @@ packages: - supports-color dev: true - /@extollo/lib/0.14.8: - resolution: {integrity: sha512-W98WJd8GIcLfQlqfqlsy0WkHWuHYEV929oEMktjP1Mf66n31Vu9S13Pds3wki3/CKVQ4wdOm4OEZstWAy+cHQA==} + /@extollo/lib/0.14.10: + resolution: {integrity: sha512-lAQxRRR7Dn7oIV3lDlKs0f6tRkhFGkFBjylfo+kcfHIxEzItnyvg3XNJtZ/xGiQuERnF0eMO+Cd5YsT0zeDouQ==} dependencies: '@atao60/fse-cli': 0.1.7 '@extollo/ui': 0.1.0_@types+node@14.18.33 diff --git a/src/app/configs/cors.config.ts b/src/app/configs/cors.config.ts new file mode 100644 index 0000000..111a47b --- /dev/null +++ b/src/app/configs/cors.config.ts @@ -0,0 +1,12 @@ +import {env, HTTPMethod} from '@extollo/lib' + +export default { + enable: env('ENABLE_CORS', false), + allow: { + origins: [ + 'https://garrettmills.dev', + 'https://glmdev.tech', + ] as string[], + methods: ['post', 'get', 'options'] as HTTPMethod[], + }, +} diff --git a/src/app/configs/server.config.ts b/src/app/configs/server.config.ts index 5b92fd1..bbf4d9c 100644 --- a/src/app/configs/server.config.ts +++ b/src/app/configs/server.config.ts @@ -8,6 +8,7 @@ import { CacheQueue, BusConnectorConfig, QueueConfig, SyncQueue } from '@extollo/lib' +import {CORS} from '../http/middlewares/CORS.middleware' export default { debug: env('DEBUG_MODE', false), @@ -61,7 +62,7 @@ export default { middleware: { global: { - pre: [], + pre: [CORS], }, }, } diff --git a/src/app/http/middlewares/CORS.middleware.ts b/src/app/http/middlewares/CORS.middleware.ts new file mode 100644 index 0000000..a1653ee --- /dev/null +++ b/src/app/http/middlewares/CORS.middleware.ts @@ -0,0 +1,48 @@ +import {Middleware, Injectable, Inject, Config, HTTPMethod, Response, HTTPStatus, http, Logging} from '@extollo/lib' + +/** + * CORS Middleware + * -------------------------------------------- + * Put some description here. + */ +@Injectable() +export class CORS extends Middleware { + @Inject() + protected readonly config!: Config + + @Inject() + protected readonly logging!: Logging + + public async apply() { + this.logging.debug('CORS Middleware') + if ( !this.config.get('cors.enable', false) ) { + this.logging.debug('Will not send CORS headers: CORS is disabled.') + return + } + + const response: Response = this.request.response + response.setHeader('Access-Control-Allow-Headers', '*') + + if ( this.config.get('server.debug', false) ) { + response.setHeader('Access-Control-Allow-Origin', '*') + response.setHeader('Access-Control-Allow-Methods', '*') + + if ( this.request.method === 'options' ) { + return http(HTTPStatus.NO_CONTENT) + } + + return + } + + const origins = this.config.get('cors.allow.origins', []) as string[] + response.setHeader('Access-Control-Allow-Origin', origins.join(',')) + + const methods = this.config.get('cors.allow.methods') as HTTPMethod[] + response.setHeader('Access-Control-Allow-Methods', methods.map(x => x.toUpperCase()).join(',')) + + if ( this.request.method === 'options' ) { + response.setStatus(HTTPStatus.NO_CONTENT) + return '' + } + } +} diff --git a/src/app/http/routes/app.routes.ts b/src/app/http/routes/app.routes.ts index fc16a39..e251c9a 100644 --- a/src/app/http/routes/app.routes.ts +++ b/src/app/http/routes/app.routes.ts @@ -1,4 +1,4 @@ -import {redirect, Route, SessionAuthMiddleware} from '@extollo/lib' +import {redirect, Route, SessionAuthMiddleware, api} from '@extollo/lib' import {Home} from '../controllers/Home.controller' import {PageView} from '../middlewares/PageView.middleware' import {Snippets} from '../controllers/Snippets.controller' @@ -9,6 +9,9 @@ import {LoadFeedPosts} from '../middlewares/parameters/LoadFeedPosts.middleware' import {ValidContactForm} from '../middlewares/parameters/ValidContactForm.middleware' import {RateLimit} from '../middlewares/RateLimit.middleware' +Route.endpoint('options', '**') + .handledBy(() => api.one({})) + Route .group('/', () => { Route.get('/')