Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Feature - Authentication Middleware Injection #123

Merged
merged 17 commits into from
Apr 1, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.schema
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
ALLOWED_ORIGINS=
AUDIT_ENABLED=
CORS_ENABLED=
DB_HOST=
DB_NAME=
DB_PASSWORD=
Expand All @@ -9,5 +11,5 @@ ID_CUSTOM_SIZE=
ID_USELOCAL=
LECTERN_URL=
LOG_LEVEL=
PORT=3030
PLURALIZE_SCHEMAS_ENABLED=
PORT=3030
34 changes: 19 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ The structure of this monorepo is app centric having `apps/` folder to keep depl
- [Lectern](https://github.com/overture-stack/lectern) Dictionary Management and validation
- [Postgres Database](https://www.postgresql.org/) For data storage

> Note: A `docker-compose.yml` file is provided to help spin up the system dependencies

## Local development

### Development tools
Expand Down Expand Up @@ -72,21 +74,23 @@ Create a `.env` file based on `.env.schema` located on the root folder and set t

The Environment Variables used for this application are listed in the table bellow

| Name | Description | Default |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- |
| `AUDIT_ENABLED` | Ensures that any modifications to the submitted data are logged, providing a way to identify who made changes and when they were made. | true |
| `DB_HOST` | Database Hostname | |
| `DB_NAME` | Database Name | |
| `DB_PASSWORD` | Database Password | |
| `DB_PORT` | Database Port | |
| `DB_USER` | Database User | |
| `ID_CUSTOM_ALPHABET` | Custom Alphabet for local ID generation | '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
| `ID_CUSTOM_SIZE` | Custom size of ID for local ID generation | 21 |
| `ID_USELOCAL` | Generate ID locally | true |
| `LECTERN_URL` | Schema Service (Lectern) URL | |
| `LOG_LEVEL` | Log Level | 'info' |
| `PLURALIZE_SCHEMAS_ENABLED` | This feature automatically convert schema names to their plural forms when handling compound documents. Pluralization assumes the words are in English | true |
| `PORT` | Server Port. | 3030 |
| Name | Description | Default |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- |
| `ALLOWED_ORIGINS` | Specifies a list of permitted origins for Cross-Origin Resource Sharing (CORS). These origins, separated by commas, are allowed to make requests to the server, ensuring only trusted domains can access resources. (Example: https://www.example.com,https://subdomain.example.com) | |
| `AUDIT_ENABLED` | Ensures that any modifications to the submitted data are logged, providing a way to identify who made changes and when they were made. | true |
| `CORS_ENABLED` | Controls whether the CORS functionality is enabled or disabled. | false |
| `DB_HOST` | Database Hostname | |
| `DB_NAME` | Database Name | |
| `DB_PASSWORD` | Database Password | |
| `DB_PORT` | Database Port | |
| `DB_USER` | Database User | |
| `ID_CUSTOM_ALPHABET` | Custom Alphabet for local ID generation | '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' |
| `ID_CUSTOM_SIZE` | Custom size of ID for local ID generation | 21 |
| `ID_USELOCAL` | Generate ID locally | true |
| `LECTERN_URL` | Schema Service (Lectern) URL | |
| `LOG_LEVEL` | Log Level | 'info' |
| `PLURALIZE_SCHEMAS_ENABLED` | This feature automatically convert schema names to their plural forms when handling compound documents. Pluralization assumes the words are in English | true |
| `PORT` | Server Port. | 3030 |

## Script commands (Workspace)

Expand Down
2 changes: 2 additions & 0 deletions apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"private": true,
"dependencies": {
"@overture-stack/lyric": "workspace:^",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"helmet": "^7.1.0",
Expand All @@ -31,6 +32,7 @@
"winston": "^3.13.1"
},
"devDependencies": {
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/express-serve-static-core": "^4.19.5",
"@types/qs": "^6.9.15",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { AppConfig } from '@overture-stack/lyric';
export const getServerConfig = () => {
return {
port: process.env.PORT || 3030,
allowedOrigins: process.env.ALLOWED_ORIGINS?.split(',') || [],
corsEnabled: getBoolean(process.env.CORS_ENABLED, false),
};
};

Expand All @@ -27,7 +29,10 @@ const getRequiredConfig = (name: string) => {
return value;
};

export const defaultAppConfig: AppConfig = {
export const appConfig: AppConfig = {
auth: {
enabled: false,
},
db: {
host: getRequiredConfig('DB_HOST'),
port: Number(getRequiredConfig('DB_PORT')),
Expand All @@ -48,10 +53,10 @@ export const defaultAppConfig: AppConfig = {
customAlphabet: process.env.ID_CUSTOM_ALPHABET || '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ',
customSize: Number(process.env.ID_CUSTOM_SIZE) || 21,
},
schemaService: {
url: getRequiredConfig('LECTERN_URL'),
},
logger: {
level: process.env.LOG_LEVEL || 'info',
},
schemaService: {
url: getRequiredConfig('LECTERN_URL'),
},
};
6 changes: 3 additions & 3 deletions apps/server/src/config/swagger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ import swaggerJSDoc from 'swagger-jsdoc';

import { version } from './manifest.js';

const swaggerDefinition = {
const swaggerDefinition: swaggerJSDoc.OAS3Definition = {
failOnErrors: true, // Whether or not to throw when parsing errors. Defaults to false.
openapi: '3.0.0',
openapi: '3.0.1',
info: {
title: 'Lyric',
version,
},
};

const options = {
const options: swaggerJSDoc.OAS3Options = {
swaggerDefinition,
// Paths to files containing OpenAPI definitions
apis: ['./src/routes/*.ts', './swagger/*.yml'],
Expand Down
29 changes: 24 additions & 5 deletions apps/server/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,42 @@
import cors from 'cors';
import express from 'express';
import helmet from 'helmet';
import { serve, setup } from 'swagger-ui-express';

import { errorHandler, provider } from '@overture-stack/lyric';

import { defaultAppConfig, getServerConfig } from './config/server.js';
import { appConfig, getServerConfig } from './config/app.js';
import swaggerDoc from './config/swagger.js';
import healthRouter from './routes/health.js';
import pingRouter from './routes/ping.js';

const serverConfig = getServerConfig();
const { allowedOrigins, port, corsEnabled } = getServerConfig();

const lyricProvider = provider(defaultAppConfig);
const lyricProvider = provider(appConfig);

// Create Express server
const app = express();

app.use(helmet());

app.use(
cors({
origin: function (origin, callback) {
// If CORS is disabled, allow the request regardless of the origin
if (!corsEnabled) {
return callback(null, true);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want to add a feature flag (env var config) to enable this, and have it disabled by default?
doesn't feel right to just have it "open" like this

Copy link
Contributor Author

@leoraba leoraba Jan 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for noticing this. In regards to security this should be disabled by default.
And could be converted into a variable named CORS_ENABLED where when true only registered domains can access the server, otherwise rejected (default)

}

// If the origin is in the allowed origins list, allow the request
if (origin && allowedOrigins.indexOf(origin) !== -1) {
return callback(null, true);
}
const msg = 'The CORS policy for this site does not allow access from the specified Origin.';
return callback(new Error(msg), false);
},
}),
);

// Ping Route
app.use('/ping', pingRouter);

Expand All @@ -35,6 +54,6 @@ app.use('/health', healthRouter);

app.use(errorHandler);
// running the server
app.listen(serverConfig.port, () => {
console.log(`Starting Express server on http://localhost:${serverConfig.port}`);
app.listen(port, () => {
console.log(`Starting ExpressJS server on port ${port}`);
});
7 changes: 7 additions & 0 deletions apps/server/swagger/schemas.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ components:
type: string
decription: Description of the error

Forbidden:
description: Error response indicating invalid access due to inadequate permissions
content:
application/json:
schema:
$ref: '#/components/responses/Error'

NotFound:
description: Requested resource could not be found
content:
Expand Down
28 changes: 28 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ version: '3.9'

services:
postgres:
container_name: lyric.db
image: postgres:15-alpine
ports:
- 5432:5432
Expand All @@ -11,3 +12,30 @@ services:
- POSTGRES_PASSWORD=secret
- POSTGRES_USER=postgres
- POSTGRES_DB=lyric
lectern_mongo:
container_name: lyric.lectern.db
image: bitnami/mongodb:4.0
ports:
- 27017:27017
volumes:
- mongodb_data:/bitnami
environment:
MONGODB_USERNAME: admin
MONGODB_PASSWORD: password
MONGODB_DATABASE: lectern
MONGODB_ROOT_PASSWORD: password123
lectern_service:
container_name: lyric.lectern.service
image: ghcr.io/overture-stack/lectern:latest
ports:
- 3000:3000
environment:
MONGO_HOST: lectern_mongo
MONGO_PORT: 27017
MONGO_DB: lectern
MONGO_USER: admin
MONGO_PASS: password
volumes:
mongodb_data:
name: lectern-mongo-data
driver: local
Loading