diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..8f70a40 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,282 @@ +kind: pipeline +type: docker +name: Test Pipeline + +workspace: + path: /drone/auth + +steps: +- name: yarn install + image: node:latest + commands: + - yarn install +- name: Code Style Checks + image: node:latest + commands: + - yarn prettier +- name: Lint + image: node:latest + commands: + - yarn lint +- name: Unit Tests + image: node:latest + commands: + - yarn test +- name: Send Test Status Notification + image: plugins/webhook + settings: + urls: https://lab.mifi.dev/hooks/9p65zpagctgkmndo8nwwm4199r + content_type: application/json + template: | + { + "icon_url":"https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/freezing-face_1f976.png", + "text": "[{{ repo.name }} - Build # {{ build.number }}] Code Quality Checks {{ build.status }} {{#success build.status}}:tada:{{else}}:poop:{{/success}}", + "username":"DroneBot" + } + when: + status: + - success + - failure +- name: Build + image: node:latest + commands: + - yarn build +- name: Send Build Status Notifications + image: plugins/webhook + settings: + urls: https://lab.mifi.dev/hooks/9p65zpagctgkmndo8nwwm4199r + content_type: application/json + template: | + { + "icon_url":"https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/freezing-face_1f976.png", + "text": "[{{ repo.name }} - Build # {{ build.number }}] Build package {{ build.status }} {{#success build.status}}:tada:{{else}}:poop:{{/success}}", + "username":"DroneBot" + } + when: + status: + - success + - failure + +trigger: + branch: + - main + - develop + event: + - pull_request + +--- +kind: pipeline +type: docker +name: Publish Pipeline + +workspace: + path: /drone/auth + +steps: +- name: Build Package + image: node:latest + commands: + - yarn install + - yarn build +- name: Publish NPM + image: node:20-alpine + failure: ignore + commands: + - yarn publish -t ${DRONE_TAG} + volumes: + - name: npmrc + path: /drone/auth/.npmrc +- name: Report NPM Publish Status + image: plugins/webhook + settings: + urls: https://lab.mifi.dev/hooks/ccw34hdf7tgbjmzp96nptn938r + content_type: application/json + template: | + { + "icon_url":"https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/freezing-face_1f976.png", + "text": "[{{ repo.name }} - New npm package release {{tag}} from # {{ build.number }}] Deploy {{ build.status }} {{#success build.status}}:tada:{{else}}:poop:{{/success}}", + "username":"DroneBot" + } + when: + status: + - success + - failure +- name: Publish Image + image: plugins/docker + settings: + auto_tag: true + repo: git.mifi.dev/mifi/auth-service + registry: git.mifi.dev + debug: true + ssh-agent-key: + from_secret: reg_token + username: + password: + from_secret: reg_token + secrets: [reg_token] +- name: Report Image Publish Status + image: plugins/webhook + settings: + urls: https://lab.mifi.dev/hooks/ccw34hdf7tgbjmzp96nptn938r + content_type: application/json + template: | + { + "icon_url":"https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/freezing-face_1f976.png", + "text": "[{{ repo.name }} - New docker image release {{tag}} from # {{ build.number }}] Deploy {{ build.status }} {{#success build.status}}:tada:{{else}}:poop:{{/success}}", + "username":"DroneBot" + } + when: + status: + - success + - failure + +volumes: +- name: dockerconfig + host: + path: /volume1/docker/dockerconfig.json +- name: dockersock + host: + path: /var/run/docker.sock +- name: npmrc + host: + path: /volume1/docker/beethoven/labs-auth/.npmrc + +depends_on: + - Test Pipeline + +trigger: + event: + - tag + +--- +kind: pipeline +type: docker +name: Staging Deploy Pipeline + +workspace: + path: /drone/auth + +steps: +- name: Deploy Container + image: docker + privileged: true + environment: + CONTAINER_PREFIX: staging + HOST: area51.mifi.dev + ROUTE_PREFIX: /auth + PORT: 9001 + commands: + - docker compose -f docker-compose.staging-build.yml build --pull --no-cache + - docker compose -f docker-compose.staging-build.yml up --remove-orphans --force-recreate --wait + volumes: + - name: env-secrets + path: /drone/auth/staging.env + - name: dockersock + path: /var/run/docker.sock + - name: dockerconfig + path: /drone/auth/.docker/config.json +- name: Send Status Notifications + image: plugins/webhook + privileged: true + settings: + urls: https://lab.mifi.dev/hooks/ccw34hdf7tgbjmzp96nptn938r + content_type: application/json + template: | + { + "icon_url":"https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/freezing-face_1f976.png", + "text": "[{{ repo.name }} - Build # {{ build.number }}] Deploy {{ build.status }} {{#success build.status}}:tada:{{else}}:poop:{{/success}}", + "username":"DroneBot" + } + when: + status: + - success + - failure + +volumes: +- name: dockerconfig + host: + path: /volume1/docker/dockerconfig.json +- name: dockersock + host: + path: /var/run/docker.sock +- name: env-secrets + host: + path: /volume1/docker/beethoven/labs-auth/staging.env + +depends_on: + - Test Pipeline + +trigger: + branch: + - develop + event: + - push + +--- +kind: pipeline +type: docker +name: Production Deploy Pipeline + +workspace: + path: /drone/auth + +clone: + disable: true + +steps: +- name: Deploy Container + image: docker + privileged: true + environment: + CONTAINER_PREFIX: staging + HOST: area51.mifi.dev + ROUTE_PREFIX: /auth + PORT: 9001 + commands: + - docker compose -f docker-compose.production-build.yml pull + - docker compose -f docker-compose.production-build.yml build --no-cache + - docker compose -f docker-compose.production-build.yml rm --stop + - docker compose -f docker-compose.production-build.yml up --wait + volumes: + - name: env-secrets + path: /drone/auth/production.env + - name: dockersock + path: /var/run/docker.sock + - name: dockerconfig + path: /drone/auth/.docker/config.json +- name: Send Status Notifications + image: plugins/webhook + privileged: true + settings: + urls: https://lab.mifi.dev/hooks/ccw34hdf7tgbjmzp96nptn938r + content_type: application/json + template: | + { + "icon_url":"https://emojipedia-us.s3.dualstack.us-west-1.amazonaws.com/thumbs/120/apple/198/freezing-face_1f976.png", + "text": "[{{ repo.name }} - Build # {{ build.number }}] Deploy {{ build.status }} {{#success build.status}}:tada:{{else}}:poop:{{/success}}", + "username":"DroneBot" + } + when: + status: + - success + - failure + +volumes: +- name: dockerconfig + host: + path: /volume1/docker/dockerconfig.json +- name: dockersock + host: + path: /var/run/docker.sock +- name: env-secrets + host: + path: /volume1/docker/beethoven/labs-auth/staging.env + +depends_on: + - Test Pipeline + +trigger: + event: + - promote + target: + - production \ No newline at end of file diff --git a/.env.dev b/.env.dev new file mode 100644 index 0000000..cf9b280 --- /dev/null +++ b/.env.dev @@ -0,0 +1,31 @@ +HOST=localhost +PORT=9001 + +ROUTE_PREFIX=/auth + +LOGIN_ROUTE=/login +RESET_ROUTE=/reset + +DB_ADMIN_USERNAME=root +DB_ADMIN_PASSWORD=password +DB_USERNAME=user +DB_PASSWORD=password +DB_NAME=auth + +MONGO_INITDB_ROOT_USERNAME=$DB_ADMIN_USERNAME +MONGO_INITDB_ROOT_PASSWORD=$DB_ADMIN_PASSWORD +MONGO_INITDB_DATABASE=$DB_NAME + +SESSION_KEY=shjhakjfhfjdshjksdhfdshfhfduyeyb73te4 + +JWT_AUDIENCE=Grow.io +JWT_ISSUER=Grow Latch +JWT_SECRET=Th!sIs a d3v3lopm3nt server SEcr¢T. + +LOGIN_VALID_TIMEOUT=12h +RESET_VALID_TIMEOUT=15m +DEFAULT_TOKEN_DAYS=1 + +CONTAINER_PREFIX=dev +SERVICE_NAME=auth-service +ENV=development diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..e8a534a --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,19 @@ +/* eslint-env node */ +module.exports = { + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:import/errors', + 'plugin:prettier/recommended', + 'prettier', + ], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + settings: { + 'import/parsers': { + '@typescript-eslint/parser': [".ts", ".tsx"], + }, + 'import/resolver': 'typescript', + }, + root: true, +}; diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..f0c3079 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,7 @@ +module.exports = { + parser: 'typescript', + printWidth: 120, + trailingComma: 'all', + tabWidth: 4, + singleQuote: true, +}; diff --git a/babel.config.js b/babel.config.js index 6432e2b..ff4c734 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,6 +1 @@ -module.exports = { - presets: [ - ['@babel/preset-env', { targets: { node: 'current' } }], - '@babel/preset-typescript', - ], -}; \ No newline at end of file +export const presets = [['@babel/preset-env', { targets: { node: 'current' } }], '@babel/preset-typescript']; diff --git a/lib/middleware/errorHandler.ts b/lib/middleware/errorHandler.ts index b91aa2f..e1da5ff 100644 --- a/lib/middleware/errorHandler.ts +++ b/lib/middleware/errorHandler.ts @@ -4,6 +4,7 @@ import { Context, Next } from 'koa'; export const errorHandler = async (ctx: Context, next: Next) => { try { await next(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any } catch (error: any) { ctx.status = error.statusCode || error.status || StatusCodes.INTERNAL_SERVER_ERROR; error.status = ctx.status; diff --git a/lib/passport/strategies/local.ts b/lib/passport/strategies/local.ts index b7dc829..d5af2b3 100644 --- a/lib/passport/strategies/local.ts +++ b/lib/passport/strategies/local.ts @@ -3,7 +3,7 @@ import { Strategy as LocalStrategy } from 'passport-local'; import { authenticate } from '@mifi/auth-db/lib/api/authenticate'; -export default new LocalStrategy(async (username: string, password: string, done: any) => { +export default new LocalStrategy(async (username, password, done) => { const user = await authenticate(username, password); done(null, user); });