feat: implement base db support
feat: implement dev containers
This commit is contained in:
parent
ca8ee728fb
commit
a71c33c085
22 changed files with 1408 additions and 262 deletions
63
.devcontainer/devcontainer.json
Normal file
63
.devcontainer/devcontainer.json
Normal file
|
@ -0,0 +1,63 @@
|
|||
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
|
||||
// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-docker-compose
|
||||
{
|
||||
"name": "waterwolf-auth",
|
||||
// Update the 'dockerComposeFile' list if you have more compose files or use different names.
|
||||
// The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
|
||||
"dockerComposeFile": ["../docker-compose.yml", "docker-compose.yml"],
|
||||
// The 'service' property is the name of the service for the container that VS Code should
|
||||
// use. Update this value and .devcontainer/docker-compose.yml to the real service name.
|
||||
"service": "waterwolf-auth",
|
||||
// The optional 'workspaceFolder' property is the path VS Code should open by default when
|
||||
// connected. This is typically a file mount in .devcontainer/docker-compose.yml
|
||||
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
|
||||
"features": {
|
||||
"ghcr.io/cirolosapio/devcontainers-features/alpine-git:0": {}
|
||||
},
|
||||
// Features to add to the dev container. More info: https://containers.dev/features.
|
||||
// "features": {},
|
||||
// Use 'forwardPorts' to make a list of ports inside the container available locally.
|
||||
"forwardPorts": [3000, "mysql:3306"],
|
||||
|
||||
"portsAttributes": {
|
||||
"3000": {
|
||||
"label": "Application port"
|
||||
},
|
||||
"9464": {
|
||||
"label": "Metrics port",
|
||||
"onAutoForward": "ignore"
|
||||
},
|
||||
"mysql:3306": {
|
||||
"label": "MySQL"
|
||||
}
|
||||
},
|
||||
// Uncomment the next line if you want start specific services in your Docker Compose config.
|
||||
// "runServices": [],
|
||||
// Uncomment the next line if you want to keep your containers running after VS Code shuts down.
|
||||
// "shutdownAction": "none",
|
||||
// Uncomment the next line to run commands after the container is created.
|
||||
"postCreateCommand": "./.devcontainer/postCreateCommand.sh",
|
||||
// Configure tool-specific properties.
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"editorconfig.editorconfig",
|
||||
"github.vscode-github-actions",
|
||||
"visualstudioexptteam.vscodeintellicode",
|
||||
"orta.vscode-jest",
|
||||
"eamodio.gitlens",
|
||||
"firsttris.vscode-jest-runner",
|
||||
"christian-kohler.path-intellisense",
|
||||
"esbenp.prettier-vscode",
|
||||
"rvest.vs-code-prettier-eslint",
|
||||
"steoates.autoimport",
|
||||
"pmneo.tsimporter",
|
||||
"christian-kohler.npm-intellisense",
|
||||
"rohinivsenthil.rabbitrace"
|
||||
]
|
||||
}
|
||||
}
|
||||
// Uncomment to connect as an existing user other than the container default. More info: https://aka.ms/dev-containers-non-root.
|
||||
// "remoteUser": "devcontainer"
|
||||
}
|
26
.devcontainer/docker-compose.yml
Normal file
26
.devcontainer/docker-compose.yml
Normal file
|
@ -0,0 +1,26 @@
|
|||
version: '3.8'
|
||||
services:
|
||||
# Update this to the name of the service you want to work with in your docker-compose.yml file
|
||||
waterwolf-auth:
|
||||
# Uncomment if you want to override the service's Dockerfile to one in the .devcontainer
|
||||
# folder. Note that the path of the Dockerfile and context is relative to the *primary*
|
||||
# docker-compose.yml file (the first in the devcontainer.json "dockerComposeFile"
|
||||
# array). The sample below assumes your primary file is in the root of your project.
|
||||
#
|
||||
# build:
|
||||
# context: .
|
||||
# dockerfile: .devcontainer/Dockerfile
|
||||
|
||||
volumes:
|
||||
# Update this to wherever you want VS Code to mount the folder of your project
|
||||
- ..:/workspaces:cached
|
||||
|
||||
# Uncomment the next four lines if you will use a ptrace-based debugger like C++, Go, and Rust.
|
||||
# cap_add:
|
||||
# - SYS_PTRACE
|
||||
# security_opt:
|
||||
# - seccomp:unconfined
|
||||
|
||||
# Overrides default command so things don't shut down after the process ends.
|
||||
command: /bin/sh -c "while sleep 1000; do :; done"
|
||||
|
140
.dockerignore
Normal file
140
.dockerignore
Normal file
|
@ -0,0 +1,140 @@
|
|||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
.cache
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
# .next
|
||||
# out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
.cache/
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
.temp
|
||||
.cache
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
.vscode-test
|
||||
|
||||
bin/
|
||||
|
||||
# yarn v2
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
keys/
|
||||
|
||||
.git
|
||||
.gitignore
|
||||
.github
|
||||
Dockerfile
|
||||
.dockerignore
|
||||
**/README.md
|
58
Dockerfile
Normal file
58
Dockerfile
Normal file
|
@ -0,0 +1,58 @@
|
|||
# base environment
|
||||
FROM node:22.4.1-alpine3.20 AS base-stage
|
||||
RUN mkdir /app && chown -R node:node /app
|
||||
WORKDIR /app
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
RUN corepack enable
|
||||
|
||||
# dependency environment
|
||||
FROM base-stage AS dependency-stage
|
||||
USER node
|
||||
COPY --link --chown=1000:1000 package*.json pnpm-lock.yaml ./
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile
|
||||
|
||||
# test stage to stop at for testing
|
||||
FROM dependency-stage AS all-source-stage
|
||||
COPY --link --chown=1000:1000 . .
|
||||
|
||||
# lint
|
||||
FROM all-source-stage AS lint
|
||||
RUN npm run lint -- --no-fix
|
||||
|
||||
# test-e2e
|
||||
FROM all-source-stage AS test-e2e
|
||||
USER root
|
||||
RUN mkdir /keys
|
||||
USER node
|
||||
RUN --mount=type=secret,id=cookies,target=/keys/cookies.json,uid=1000,gid=1000,required=true \
|
||||
--mount=type=secret,id=jwks,target=/keys/jwks.json,uid=1000,gid=1000,required=true \
|
||||
npm run test:e2e:cov -- --ci --json --testLocationInResults --outputFile=/tmp/report.json
|
||||
|
||||
# Just the e2e report file
|
||||
FROM scratch AS test-stage
|
||||
COPY --link --from=test-e2e /tmp/report.json /
|
||||
|
||||
# build environment
|
||||
FROM dependency-stage AS build-stage
|
||||
COPY --link --chown=1000:1000 . .
|
||||
RUN npm run build
|
||||
|
||||
# prod dependency environment
|
||||
FROM build-stage AS production-dependency-stage
|
||||
RUN npm prune --production
|
||||
|
||||
# production environment
|
||||
FROM base-stage AS production-stage
|
||||
RUN apk add --no-cache tini
|
||||
USER node
|
||||
|
||||
COPY --link --chown=1000:1000 --from=production-dependency-stage /app /app
|
||||
|
||||
ENV NODE_ENV=production
|
||||
|
||||
ENTRYPOINT ["/sbin/tini", "--"]
|
||||
CMD ["node", "/app/.dist/src/main.js"]
|
||||
|
||||
ARG VERSION
|
||||
ENV VERSION=${VERSION}
|
38
README.md
38
README.md
|
@ -1,8 +1,27 @@
|
|||
## Waterwolf Identity Solution
|
||||
# Waterwolf Identity Solution
|
||||
|
||||
This is a re-imagination on how BOOP works with an optimized OAUTH 2.0 flow. This will hook into the existing user database to read usernames and passwords.
|
||||
## Description
|
||||
|
||||
This is the identity service for the Waterwolf project. It is a NestJS application that provides an API for managing users and authentication.
|
||||
|
||||
## Development
|
||||
|
||||
To get started with development, first clone the repository.
|
||||
|
||||
Create a GitHub classic PAT with permission to read repos and packages in order to be able to install the private furality npm packages .
|
||||
https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic
|
||||
Create the token and put it in a file in the root of the repository named `.github_token`.
|
||||
|
||||
Then install vscode which supports devcontainers and open the repository in vscode as a devcontainer.
|
||||
This will set up all the necessary supporting services needed to run, test, and debug this service.
|
||||
|
||||
Once it finishes building initially, goto the testing tab of vscode and run the tests to make sure
|
||||
they pass and that your environment is properly set up.
|
||||
|
||||
Next, you can start up the app by going to the run and debug tab and selecting the `nest start watch` task.
|
||||
Once it is started, in the bottom pane of vscode, goto the PORTS tab and look for the `Application port` row.
|
||||
Either right click or copy the forwarded address to open it in your browser and then navigate to the path:
|
||||
http://localhost:{PORT}/v1/api/ to ensure it has started correctly
|
||||
|
||||
## Installation
|
||||
|
||||
|
@ -17,3 +36,18 @@ pnpm install
|
|||
```bash
|
||||
pnpm start
|
||||
```
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
This uses `@nestjs/config` which uses [dotenv](https://github.com/motdotla/dotenv).
|
||||
Configuration can be done by using a `.env` file or environment variables.
|
||||
|
||||
Mailing Configuration
|
||||
- `POSTAL_BASE_URL` - Base URL for the Postal API
|
||||
- `POSTAL_API_KEY` - API Key for the Postal API
|
||||
|
||||
## Credits
|
||||
|
||||
- [ConiCaw](https://github.com/ttshivers) - Teaching Kakious about documentation and base documenation from other projects
|
||||
- [Kakious](https://rawr.ing) - Main Developer and Documentation Writer
|
28
docker-compose.yml
Normal file
28
docker-compose.yml
Normal file
|
@ -0,0 +1,28 @@
|
|||
version: '3.8'
|
||||
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:latest
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
MYSQL_ROOT_PASSWORD: password
|
||||
MYSQL_DATABASE: waterwolf-auth
|
||||
volumes:
|
||||
- mysql-data:/var/lib/mysql
|
||||
redis:
|
||||
image: redis/redis-stack-server:6.2.2-v5
|
||||
restart: unless-stopped
|
||||
waterwolf-auth:
|
||||
depends_on:
|
||||
- mysql
|
||||
- redis
|
||||
build:
|
||||
context: .
|
||||
target: all-source-stage
|
||||
restart: unless-stopped
|
||||
expose:
|
||||
- '3000'
|
||||
stdin_open: true
|
||||
tty: true
|
||||
volumes:
|
||||
mysql-data:
|
1
keys/cookies.json
Normal file
1
keys/cookies.json
Normal file
|
@ -0,0 +1 @@
|
|||
['THIS IS A SECURE THING']
|
0
keys/jwks.json
Normal file
0
keys/jwks.json
Normal file
18
package.json
18
package.json
|
@ -18,25 +18,34 @@
|
|||
"test:cov": "jest --coverage",
|
||||
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
|
||||
"test:e2e": "jest --config ./test/jest-e2e.json",
|
||||
"typeorm": "ts-node --project tsconfig.json ./node_modules/typeorm/cli",
|
||||
"typeorm:run-migrations": "npm run typeorm migration:run -- -d ./src/app.datasource.ts",
|
||||
"typeorm:generate-migration": "npm run typeorm -- -d ./src/app.datasource.ts migration:generate ./src/database/migrations/$npm_config_name",
|
||||
"typeorm:create-migration": "npm run typeorm -- migration:create ./src/database/migrations/$npm_config_name",
|
||||
"typeorm:revert-migration": "npm run typeorm -- -d ./src/app.datasource.ts migration:revert",
|
||||
"prepare": "ts-patch install && typia patch"
|
||||
},
|
||||
"dependencies": {
|
||||
"@atech/postal": "^1.0.0",
|
||||
"@nestjs/bullmq": "^10.1.1",
|
||||
"@nestjs/common": "^10.3.10",
|
||||
"@nestjs/config": "^3.2.3",
|
||||
"@nestjs/core": "^10.3.10",
|
||||
"@nestjs/platform-express": "^10.3.10",
|
||||
"@nestjs/typeorm": "^10.0.2",
|
||||
"bullmq": "^5.9.0",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.1",
|
||||
"dotenv": "^16.4.5",
|
||||
"ioredis": "^5.4.1",
|
||||
"mysql2": "^3.10.2",
|
||||
"nanoid": "^5.0.7",
|
||||
"nestjs-postal-client": "^0.0.5",
|
||||
"nestjs-postal-client": "^0.0.6",
|
||||
"oidc-provider": "^8.5.1",
|
||||
"pug": "^3.0.3",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"rxjs": "^7.8.1",
|
||||
"sequelize": "^6.37.3",
|
||||
"sequelize-typescript": "^2.1.6",
|
||||
"typeorm": "^0.3.20",
|
||||
"typia": "^6.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -46,7 +55,6 @@
|
|||
"@types/express": "^4.17.21",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^20.14.10",
|
||||
"@types/sequelize": "^4.28.20",
|
||||
"@types/supertest": "^6.0.2",
|
||||
"@typescript-eslint/eslint-plugin": "^7.16.1",
|
||||
"@typescript-eslint/parser": "^7.16.1",
|
||||
|
@ -55,8 +63,10 @@
|
|||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"jest": "^29.7.0",
|
||||
"prettier": "^3.3.3",
|
||||
"sequelize-cli": "^6.6.2",
|
||||
"source-map-support": "^0.5.21",
|
||||
"supertest": "^7.0.0",
|
||||
"tailwindcss": "^3.4.5",
|
||||
"ts-jest": "^29.2.2",
|
||||
"ts-loader": "^9.5.1",
|
||||
"ts-node": "^10.9.2",
|
||||
|
|
1123
pnpm-lock.yaml
1123
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
22
src/app.datasource.ts
Normal file
22
src/app.datasource.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
import { ConfigService } from '@nestjs/config';
|
||||
import { config } from 'dotenv';
|
||||
import { DataSource } from 'typeorm';
|
||||
|
||||
import { DATABASE_MIGRATION } from './database/database.migration';
|
||||
import { DATABASE_ENTITIES } from './database/database.entities';
|
||||
|
||||
config();
|
||||
|
||||
const configService = new ConfigService();
|
||||
|
||||
export default new DataSource({
|
||||
type: 'mysql',
|
||||
host: configService.getOrThrow<string>('DATABASE_HOST'),
|
||||
port: configService.getOrThrow<number>('DATABASE_PORT'),
|
||||
username: configService.getOrThrow<string>('DATABASE_USER'),
|
||||
password: configService.getOrThrow<string>('DATABASE_PASSWORD', ''),
|
||||
database: configService.getOrThrow<string>('DATABASE_NAME'),
|
||||
charset: 'UTF8MB4',
|
||||
entities: DATABASE_ENTITIES,
|
||||
migrations: DATABASE_MIGRATION,
|
||||
});
|
12
src/auth/model/user.model.ts
Normal file
12
src/auth/model/user.model.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { IsEmail } from 'class-validator';
|
||||
import { Column, Model, Table } from 'sequelize-typescript';
|
||||
|
||||
@Table
|
||||
export class User extends Model<User> {
|
||||
@Column
|
||||
username: string;
|
||||
|
||||
@Column
|
||||
@IsEmail()
|
||||
email: string;
|
||||
}
|
68
src/auth/oidc/core.service.ts
Normal file
68
src/auth/oidc/core.service.ts
Normal file
|
@ -0,0 +1,68 @@
|
|||
import { Injectable, Logger, OnModuleInit } from '@nestjs/common';
|
||||
import type Provider from 'oidc-provider';
|
||||
import type { Configuration, errors, KoaContextWithOIDC } from 'oidc-provider';
|
||||
|
||||
// This is an async import for the oidc-provider package as it's now only esm and we need to use it in a commonjs environment.
|
||||
async function getProvider(): Promise<{
|
||||
provider: any;
|
||||
providerErrors: typeof errors;
|
||||
}> {
|
||||
let provider: {
|
||||
default: any;
|
||||
errors: typeof errors;
|
||||
};
|
||||
|
||||
// Unfortunately, there is a Node/Jest bug that causes segmentation faults when doing such an import in Jest:
|
||||
// https://github.com/nodejs/node/issues/35889
|
||||
// To work around that, we do the import differently, in case we are in a Jest test run.
|
||||
// This can be detected via the env variables: https://jestjs.io/docs/environment-variables.
|
||||
// There have been reports of `JEST_WORKER_ID` being undefined, so to be sure we check both.
|
||||
if (process.env['JEST_WORKER_ID'] ?? process.env.NODE_ENV === 'test') {
|
||||
provider = jest.requireActual('oidc-provider');
|
||||
} else {
|
||||
provider = await (eval(`import('oidc-provider')`) as Promise<{
|
||||
default: any;
|
||||
errors: typeof errors;
|
||||
}>);
|
||||
}
|
||||
|
||||
return {
|
||||
provider: provider.default,
|
||||
providerErrors: provider.errors,
|
||||
};
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
/**
|
||||
* @class OidcService
|
||||
* OidcService is the service that handles all interaction with the OIDC library and package
|
||||
*/
|
||||
export class OidcService implements OnModuleInit {
|
||||
private provider!: Provider;
|
||||
private jwks: any;
|
||||
private cookies: any;
|
||||
private readonly logger = new Logger(OidcService.name);
|
||||
|
||||
constructor() {}
|
||||
|
||||
async onModuleInit() {
|
||||
const { provider, providerErrors } = await getProvider();
|
||||
|
||||
const isOrigin = (value: string): boolean => {
|
||||
if (typeof value !== 'string') {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
const { origin } = new URL(value);
|
||||
// Origin: <scheme> "://" <hostname> [ ":" <port> ]
|
||||
return value == origin;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
private async loadKeys() {}
|
||||
}
|
0
src/auth/oidc/oidc.config.ts
Normal file
0
src/auth/oidc/oidc.config.ts
Normal file
15
src/auth/oidc/oidc.const.ts
Normal file
15
src/auth/oidc/oidc.const.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/**
|
||||
* OIDC Constants
|
||||
*/
|
||||
|
||||
// OIDC TTLs
|
||||
export const REFRESH_TOKEN_LIFE = 5 * 24 * 60 * 60; // 5 days
|
||||
export const ID_TOKEN_LIFE = 15 * 60; // 15 minutes
|
||||
export const AUTHORIZATION_TOKEN_LIFE = 30 * 60; // 1 hour
|
||||
export const SESSION_LIFE = 5 * 24 * 60 * 60; // 5 days
|
||||
export const ACCESS_TOKEN_LIFE = 15 * 60; // 15 minutes
|
||||
export const DEVICE_CODE_LIFE = 10 * 60; // 10 minutes
|
||||
export const GRANT_LIFE = 60 * 60 * 24 * 30; // 1 month
|
||||
export const INTERACTION_LIFE = 1 * 60 * 60; // 1 hour
|
||||
export const PUSHED_AUTH_REQ_LIFE = 15 * 60; // 15 minutes
|
||||
export const CLIENT_CREDENTIALS_TOKEN_LIFE = 7 * 24 * 60 * 60; // 7 days
|
|
@ -1,6 +1,6 @@
|
|||
export default async () => ({
|
||||
mail: {
|
||||
baseUrl: process.env.MAIL_BASE_URL,
|
||||
apiKey: process.env.MAIL_API_KEY,
|
||||
base: {
|
||||
port: process.env.PORT || 3000,
|
||||
host: process.env.HOST || 'localhost',
|
||||
},
|
||||
});
|
||||
|
|
0
src/database/database-config.service.ts
Normal file
0
src/database/database-config.service.ts
Normal file
8
src/database/database.const.ts
Normal file
8
src/database/database.const.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
export const MAX_STRING_LENGTH = 255;
|
||||
export const FETCH_AFTER_CREATION_FAILED =
|
||||
'Failed to fetch entity after creation';
|
||||
|
||||
export enum UserRole {
|
||||
ADMIN = 'admin',
|
||||
USER = 'user',
|
||||
}
|
4
src/database/database.entities.ts
Normal file
4
src/database/database.entities.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
import { User } from './models/user.model';
|
||||
|
||||
// Database Entities Array
|
||||
export const DATABASE_ENTITIES = [User];
|
2
src/database/database.migration.ts
Normal file
2
src/database/database.migration.ts
Normal file
|
@ -0,0 +1,2 @@
|
|||
// Database Migration Array
|
||||
export const DATABASE_MIGRATION = [];
|
29
src/database/models/user.model.ts
Normal file
29
src/database/models/user.model.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
|
||||
import { MAX_STRING_LENGTH, UserRole } from '../database.const';
|
||||
|
||||
@Entity('user')
|
||||
export class User {
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
@Column({ length: MAX_STRING_LENGTH })
|
||||
username: string;
|
||||
|
||||
@Column({ length: MAX_STRING_LENGTH })
|
||||
email: string;
|
||||
|
||||
@Column({ length: MAX_STRING_LENGTH })
|
||||
password: string;
|
||||
|
||||
@Column({ length: MAX_STRING_LENGTH, nullable: true })
|
||||
pronouns: string;
|
||||
|
||||
@Column({ length: MAX_STRING_LENGTH, nullable: true })
|
||||
title: string;
|
||||
|
||||
@Column({ length: MAX_STRING_LENGTH, nullable: true })
|
||||
avatar: string;
|
||||
|
||||
@Column({ length: 15, enum: UserRole, default: UserRole.USER })
|
||||
role: string;
|
||||
}
|
9
tailwind.config.js
Normal file
9
tailwind.config.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
|
Loading…
Reference in a new issue