From e503468660a13760010a94ecda5f0625c6f47f87 Mon Sep 17 00:00:00 2001 From: Ricardo Date: Fri, 13 Oct 2023 14:12:03 +0200 Subject: Server re-build with latest AdonisJS framework & Typescript (#47) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: setup first basis structure * chore: ensure styling is loaded correctly * chore: comply to new routing syntax by replace . with / in routes/resource locations * chore: add login controller * chore: correctly use views with slash instead of dot * chore: working login + tests * chore: clean up tests * chore: add password-forgot endpoint and matching test * chore: add delete page test * chore: add logout test * chore: add reset-password route and tests * chore: remove obsolete comment * chore: add account-page and tests * chore: add data page & first step of the test * chore: add transfer/import data feature and tests * chore: add export and basic test * chore: add all static api routes with tests * Regenerate 'pnpm-lock.json' and fix bad merge conflict WIP: - Tests have been commented out since they dont work - Server doesn't start * easier dev and test runs * - remove --require-pragma from reformat-files so formatting works properly - run pnpm reformat-files over codebase - remove .json files from .eslintignore - add invalid.json file to .eslintignore - configure prettier properly in eslint config - add type jsdoc to prettier config - run adonis generate:manifest command to regenerate ace-manifest.json - specify volta in package.json - introduce typecheck npm script - remove unused .mjs extension from npm scripts - install missing type definition dependencies - add pnpm.allowedDeprecatedVersions to package.json - fix invalid extends in tsconfig.json causing TS issues throughout codebase - remove @ts-ignore throughout codebase which is not relevant anymore - enable some of the tsconfig options - remove outdated eslint-disable from codebase - change deprecated faker.company.companyName() to faker.company.name() - fix TS issues inside transfer.spec.ts * - update to latest node and pnpm versions - upgrade all non-major dependencies to latest - install missing @types/luxon dependency - add cuid to pnpm.allowedDeprecatedVersions - add esModuleInterop config option to tsconfig - migrate more deprecated faker methods to new ones - add more temporary ts-ignore to code * - update eslint config - remove trailingComma: all since default in prettier v3 - add typecheck command to prepare-code npm script - upgrade various dependencies to latest major version - update tsconfig to include only useful config options - disable some lint issues and fix others * - add test command to prepare-code - disable strictPropertyInitialization flag in tsconfig which creates issues with adonis models - update precommit hook to excute pnpm prepare-code - remove ts-ignore statements from all models * fix node and pnpm dependency update * add cross env (so that we can develop on windows) * add signup endpoint (TODO: JWT auth) * Add login endpoint * Add me and updateMe endpoints * Add service endpoint * refactor: change endpoints to use jwt * add recipes endpoint * add workspaces endpoint * fix web controllors for login and post import * Update node deps * Change auth middleware (for web) and exempt api from CSRF * Add import endpoint (franz import) * Fix export/import logic * Fix service and workspace data in user/data * Fix partial lint * chore: workaround lint issues * fix: migration naming had two . * Sync back node with recipes repo * Temporarily ignore typescript * Fix adonisrc to handle public folder static assets * Fix issue with production database * add Legacy Password Provider * Fix lint errors * Fix issue on login errors frontend * add Legacy Password Provider * Fix issue with customIcons * Fix issue with auth tokens * Update 'node' to '18.18.0' * make docker work * improve docker entrypoint (test api performance) * Add migration database script * NODE_ENV on recipes * prefer @ts-expect-error over @ts-ignore * small fixes * Update 'pnpm' to '8.7.6' * fix error catch * Automatically generate JWT Public and Private keys * Use custom Adonis5-jwt * Update code to use secret (old way, no breaking changes) * Normalize appKey * Trick to make JWT tokens on client work with new version * Fix error with new JWT logic * Change migration and how we store JWT * Fix 500 response code (needs to be 401) * Improve logic and fix bugs * Fix build and entrypoint logic * Catch error if appKey changes * Add newToken logic * Fix lint (ignore any errors) * Add build for PRs * pnpm reformat-files result * Fix some tests * Fix reset password not working (test failing) * Restore csrfTokens (disabled by accident) * Fix pnpm start command with .env * Disable failing tests on the transfer endpoint (TODO) * Add tests to PR build * Fix build * Remove unnecessary assertStatus * Add typecheck * hash password on UserFactory (fix build) * Add JWT_USE_PEM true by default (increase security) * fix name of github action --------- Co-authored-by: Vijay A Co-authored-by: Balaji Vijayakumar Co-authored-by: MCMXC <16797721+mcmxcdev@users.noreply.github.com> Co-authored-by: André Oliveira --- config/app.js | 242 ----------------------------------------------- config/app.ts | 244 +++++++++++++++++++++++++++++++++++++++++++++++ config/auth.js | 93 ------------------ config/auth.ts | 263 +++++++++++++++++++++++++++++++++++++++++++++++++++ config/bodyParser.js | 156 ------------------------------ config/bodyparser.ts | 205 +++++++++++++++++++++++++++++++++++++++ config/cors.js | 86 ----------------- config/cors.ts | 134 ++++++++++++++++++++++++++ config/dashboard.ts | 5 + config/database.js | 88 ----------------- config/database.ts | 121 ++++++++++++++++++++++++ config/drive.js | 45 --------- config/drive.ts | 149 +++++++++++++++++++++++++++++ config/hash.js | 48 ---------- config/hash.ts | 88 +++++++++++++++++ config/mail.js | 104 -------------------- config/mail.ts | 118 +++++++++++++++++++++++ config/persona.js | 94 ------------------ config/session.js | 98 ------------------- config/session.ts | 116 +++++++++++++++++++++++ config/shield.js | 144 ---------------------------- config/shield.ts | 243 +++++++++++++++++++++++++++++++++++++++++++++++ config/static.ts | 10 ++ 23 files changed, 1696 insertions(+), 1198 deletions(-) delete mode 100644 config/app.js create mode 100644 config/app.ts delete mode 100644 config/auth.js create mode 100644 config/auth.ts delete mode 100644 config/bodyParser.js create mode 100644 config/bodyparser.ts delete mode 100644 config/cors.js create mode 100644 config/cors.ts create mode 100644 config/dashboard.ts delete mode 100644 config/database.js create mode 100644 config/database.ts delete mode 100644 config/drive.js create mode 100644 config/drive.ts delete mode 100644 config/hash.js create mode 100644 config/hash.ts delete mode 100644 config/mail.js create mode 100644 config/mail.ts delete mode 100644 config/persona.js delete mode 100644 config/session.js create mode 100644 config/session.ts delete mode 100644 config/shield.js create mode 100644 config/shield.ts create mode 100644 config/static.ts (limited to 'config') diff --git a/config/app.js b/config/app.js deleted file mode 100644 index 1951e68..0000000 --- a/config/app.js +++ /dev/null @@ -1,242 +0,0 @@ - -/** @type {import('@adonisjs/framework/src/Env')} */ -const Env = use('Env'); - -module.exports = { - - /* - |-------------------------------------------------------------------------- - | Application Name - |-------------------------------------------------------------------------- - | - | This value is the name of your application and can used when you - | need to place the application's name in a email, view or - | other location. - | - */ - - name: Env.get('APP_NAME', 'Ferdium-server'), - - /* - |-------------------------------------------------------------------------- - | App Key - |-------------------------------------------------------------------------- - | - | App key is a randomly generated 16 or 32 characters long string required - | to encrypt cookies, sessions and other sensitive data. - | - */ - appKey: Env.getOrFail('APP_KEY'), - - http: { - /* - |-------------------------------------------------------------------------- - | Allow Method Spoofing - |-------------------------------------------------------------------------- - | - | Method spoofing allows to make requests by spoofing the http verb. - | Which means you can make a GET request but instruct the server to - | treat as a POST or PUT request. If you want this feature, set the - | below value to true. - | - */ - allowMethodSpoofing: true, - - /* - |-------------------------------------------------------------------------- - | Trust Proxy - |-------------------------------------------------------------------------- - | - | Trust proxy defines whether X-Forwarded-* headers should be trusted or not. - | When your application is behind a proxy server like nginx, these values - | are set automatically and should be trusted. Apart from setting it - | to true or false Adonis supports handful or ways to allow proxy - | values. Read documentation for that. - | - */ - trustProxy: false, - - /* - |-------------------------------------------------------------------------- - | Subdomains - |-------------------------------------------------------------------------- - | - | Offset to be used for returning subdomains for a given request.For - | majority of applications it will be 2, until you have nested - | sudomains. - | cheatsheet.adonisjs.com - offset - 2 - | virk.cheatsheet.adonisjs.com - offset - 3 - | - */ - subdomainOffset: 2, - - /* - |-------------------------------------------------------------------------- - | JSONP Callback - |-------------------------------------------------------------------------- - | - | Default jsonp callback to be used when callback query string is missing - | in request url. - | - */ - jsonpCallback: 'callback', - - - /* - |-------------------------------------------------------------------------- - | Etag - |-------------------------------------------------------------------------- - | - | Set etag on all HTTP response. In order to disable for selected routes, - | you can call the `response.send` with an options object as follows. - | - | response.send('Hello', { ignoreEtag: true }) - | - */ - etag: false, - }, - - views: { - /* - |-------------------------------------------------------------------------- - | Cache Views - |-------------------------------------------------------------------------- - | - | Define whether or not to cache the compiled view. Set it to true in - | production to optimize view loading time. - | - */ - cache: Env.get('CACHE_VIEWS', true), - }, - - static: { - /* - |-------------------------------------------------------------------------- - | Dot Files - |-------------------------------------------------------------------------- - | - | Define how to treat dot files when trying to server static resources. - | By default it is set to ignore, which will pretend that dotfiles - | does not exists. - | - | Can be one of the following - | ignore, deny, allow - | - */ - dotfiles: 'ignore', - - /* - |-------------------------------------------------------------------------- - | ETag - |-------------------------------------------------------------------------- - | - | Enable or disable etag generation - | - */ - etag: true, - - /* - |-------------------------------------------------------------------------- - | Extensions - |-------------------------------------------------------------------------- - | - | Set file extension fallbacks. When set, if a file is not found, the given - | extensions will be added to the file name and search for. The first - | that exists will be served. Example: ['html', 'htm']. - | - */ - extensions: false, - }, - - locales: { - /* - |-------------------------------------------------------------------------- - | Loader - |-------------------------------------------------------------------------- - | - | The loader to be used for fetching and updating locales. Below is the - | list of available options. - | - | file, database - | - */ - loader: 'file', - - /* - |-------------------------------------------------------------------------- - | Default Locale - |-------------------------------------------------------------------------- - | - | Default locale to be used by Antl provider. You can always switch drivers - | in runtime or use the official Antl middleware to detect the driver - | based on HTTP headers/query string. - | - */ - locale: 'en', - }, - - logger: { - /* - |-------------------------------------------------------------------------- - | Transport - |-------------------------------------------------------------------------- - | - | Transport to be used for logging messages. You can have multiple - | transports using same driver. - | - | Available drivers are: `file` and `console`. - | - */ - transport: 'console', - - /* - |-------------------------------------------------------------------------- - | Console Transport - |-------------------------------------------------------------------------- - | - | Using `console` driver for logging. This driver writes to `stdout` - | and `stderr` - | - */ - console: { - driver: 'console', - name: 'adonis-app', - level: 'info', - }, - - /* - |-------------------------------------------------------------------------- - | File Transport - |-------------------------------------------------------------------------- - | - | File transport uses file driver and writes log messages for a given - | file inside `tmp` directory for your app. - | - | For a different directory, set an absolute path for the filename. - | - */ - file: { - driver: 'file', - name: 'adonis-app', - filename: 'adonis.log', - level: 'info', - }, - }, - - /* - |-------------------------------------------------------------------------- - | Generic Cookie Options - |-------------------------------------------------------------------------- - | - | The following cookie options are generic settings used by AdonisJs to create - | cookies. However, some parts of the application like `sessions` can have - | separate settings for cookies inside `config/session.js`. - | - */ - cookie: { - httpOnly: true, - sameSite: true, - path: '/', - maxAge: 7200, - }, -}; diff --git a/config/app.ts b/config/app.ts new file mode 100644 index 0000000..fb3c0be --- /dev/null +++ b/config/app.ts @@ -0,0 +1,244 @@ +/** + * Config source: https://git.io/JfefZ + * + * Feel free to let us know via PR, if you find something broken in this config + * file. + */ + +import proxyAddr from 'proxy-addr'; +import Env from '@ioc:Adonis/Core/Env'; +import { ServerConfig } from '@ioc:Adonis/Core/Server'; +import { LoggerConfig } from '@ioc:Adonis/Core/Logger'; +import { ProfilerConfig } from '@ioc:Adonis/Core/Profiler'; +import { ValidatorConfig } from '@ioc:Adonis/Core/Validator'; + +/* +|-------------------------------------------------------------------------- +| Application secret key +|-------------------------------------------------------------------------- +| +| The secret to encrypt and sign different values in your application. +| Make sure to keep the `APP_KEY` as an environment variable and secure. +| +| Note: Changing the application key for an existing app will make all +| the cookies invalid and also the existing encrypted data will not +| be decrypted. +| +*/ +export const appKey: string = Env.get('APP_KEY'); + +export const url: string = Env.get('APP_URL'); + +// TODO: this is parsed as string to be coherent with the previous version of the code we add (before migrating to AdonisJS 5) +export const isRegistrationEnabled: string = Env.get('IS_REGISTRATION_ENABLED'); +export const connectWithFranz: string = Env.get('CONNECT_WITH_FRANZ'); +export const isCreationEnabled: string = Env.get('IS_CREATION_ENABLED'); +export const jwtUsePEM: boolean = + Env.get('JWT_USE_PEM', false) || + (Env.get('JWT_PUBLIC_KEY', '') !== '' && + Env.get('JWT_PRIVATE_KEY', '') !== ''); +/* +|-------------------------------------------------------------------------- +| Http server configuration +|-------------------------------------------------------------------------- +| +| The configuration for the HTTP(s) server. Make sure to go through all +| the config properties to make keep server secure. +| +*/ +export const http: ServerConfig = { + /* + |-------------------------------------------------------------------------- + | Allow method spoofing + |-------------------------------------------------------------------------- + | + | Method spoofing enables defining custom HTTP methods using a query string + | `_method`. This is usually required when you are making traditional + | form requests and wants to use HTTP verbs like `PUT`, `DELETE` and + | so on. + | + */ + allowMethodSpoofing: false, + + /* + |-------------------------------------------------------------------------- + | Subdomain offset + |-------------------------------------------------------------------------- + */ + subdomainOffset: 2, + + /* + |-------------------------------------------------------------------------- + | Request Ids + |-------------------------------------------------------------------------- + | + | Setting this value to `true` will generate a unique request id for each + | HTTP request and set it as `x-request-id` header. + | + */ + generateRequestId: false, + + /* + |-------------------------------------------------------------------------- + | Trusting proxy servers + |-------------------------------------------------------------------------- + | + | Define the proxy servers that AdonisJs must trust for reading `X-Forwarded` + | headers. + | + */ + trustProxy: proxyAddr.compile('loopback'), + + /* + |-------------------------------------------------------------------------- + | Generating Etag + |-------------------------------------------------------------------------- + | + | Whether or not to generate an etag for every response. + | + */ + etag: false, + + /* + |-------------------------------------------------------------------------- + | JSONP Callback + |-------------------------------------------------------------------------- + */ + jsonpCallbackName: 'callback', + + /* + |-------------------------------------------------------------------------- + | Cookie settings + |-------------------------------------------------------------------------- + */ + cookie: { + domain: '', + path: '/', + maxAge: '2h', + httpOnly: true, + secure: false, + sameSite: false, + }, + + /* + |-------------------------------------------------------------------------- + | Force Content Negotiation + |-------------------------------------------------------------------------- + | + | The internals of the framework relies on the content negotiation to + | detect the best possible response type for a given HTTP request. + | + | However, it is a very common these days that API servers always wants to + | make response in JSON regardless of the existence of the `Accept` header. + | + | By setting `forceContentNegotiationTo = 'application/json'`, you negotiate + | with the server in advance to always return JSON without relying on the + | client to set the header explicitly. + | + */ + forceContentNegotiationTo: 'application/json', +}; + +/* +|-------------------------------------------------------------------------- +| Logger +|-------------------------------------------------------------------------- +*/ +export const logger: LoggerConfig = { + /* + |-------------------------------------------------------------------------- + | Application name + |-------------------------------------------------------------------------- + | + | The name of the application you want to add to the log. It is recommended + | to always have app name in every log line. + | + | The `APP_NAME` environment variable is automatically set by AdonisJS by + | reading the `name` property from the `package.json` file. + | + */ + name: Env.get('APP_NAME', 'Ferdium-server'), + + /* + |-------------------------------------------------------------------------- + | Toggle logger + |-------------------------------------------------------------------------- + | + | Enable or disable logger application wide + | + */ + enabled: true, + + /* + |-------------------------------------------------------------------------- + | Logging level + |-------------------------------------------------------------------------- + | + | The level from which you want the logger to flush logs. It is recommended + | to make use of the environment variable, so that you can define log levels + | at deployment level and not code level. + | + */ + level: Env.get('LOG_LEVEL', 'info'), + + /* + |-------------------------------------------------------------------------- + | Pretty print + |-------------------------------------------------------------------------- + | + | It is highly advised NOT to use `prettyPrint` in production, since it + | can have huge impact on performance. + | + */ + prettyPrint: Env.get('NODE_ENV') === 'development', +}; + +/* +|-------------------------------------------------------------------------- +| Profiler +|-------------------------------------------------------------------------- +*/ +export const profiler: ProfilerConfig = { + /* + |-------------------------------------------------------------------------- + | Toggle profiler + |-------------------------------------------------------------------------- + | + | Enable or disable profiler + | + */ + enabled: true, + + /* + |-------------------------------------------------------------------------- + | Blacklist actions/row labels + |-------------------------------------------------------------------------- + | + | Define an array of actions or row labels that you want to disable from + | getting profiled. + | + */ + blacklist: [], + + /* + |-------------------------------------------------------------------------- + | Whitelist actions/row labels + |-------------------------------------------------------------------------- + | + | Define an array of actions or row labels that you want to whitelist for + | the profiler. When whitelist is defined, then `blacklist` is ignored. + | + */ + whitelist: [], +}; + +/* +|-------------------------------------------------------------------------- +| Validator +|-------------------------------------------------------------------------- +| +| Configure the global configuration for the validator. Here's the reference +| to the default config https://git.io/JT0WE +| +*/ +export const validator: ValidatorConfig = {}; diff --git a/config/auth.js b/config/auth.js deleted file mode 100644 index b831b06..0000000 --- a/config/auth.js +++ /dev/null @@ -1,93 +0,0 @@ - -/** @type {import('@adonisjs/framework/src/Env')} */ -const Env = use('Env'); - -module.exports = { - /* - |-------------------------------------------------------------------------- - | Authenticator - |-------------------------------------------------------------------------- - | - | Authentication is a combination of serializer and scheme with extra - | config to define on how to authenticate a user. - | - | Available Schemes - basic, session, jwt, api - | Available Serializers - lucid, database - | - */ - authenticator: 'jwt', - - /* - |-------------------------------------------------------------------------- - | Session - |-------------------------------------------------------------------------- - | - | Session authenticator makes use of sessions to authenticate a user. - | Session authentication is always persistent. - | - */ - session: { - serializer: 'lucid', - model: 'App/Models/User', - scheme: 'session', - uid: 'email', - password: 'password', - }, - - /* - |-------------------------------------------------------------------------- - | Basic Auth - |-------------------------------------------------------------------------- - | - | The basic auth authenticator uses basic auth header to authenticate a - | user. - | - | NOTE: - | This scheme is not persistent and users are supposed to pass - | login credentials on each request. - | - */ - basic: { - serializer: 'lucid', - model: 'App/Models/User', - scheme: 'basic', - uid: 'email', - password: 'password', - }, - - /* - |-------------------------------------------------------------------------- - | Jwt - |-------------------------------------------------------------------------- - | - | The jwt authenticator works by passing a jwt token on each HTTP request - | via HTTP `Authorization` header. - | - */ - jwt: { - serializer: 'lucid', - model: 'App/Models/User', - scheme: 'jwt', - uid: 'email', - password: 'password', - options: { - secret: Env.get('APP_KEY'), - }, - }, - - /* - |-------------------------------------------------------------------------- - | Api - |-------------------------------------------------------------------------- - | - | The Api scheme makes use of API personal tokens to authenticate a user. - | - */ - api: { - serializer: 'lucid', - model: 'App/Models/User', - scheme: 'api', - uid: 'email', - password: 'password', - }, -}; diff --git a/config/auth.ts b/config/auth.ts new file mode 100644 index 0000000..28a9b8c --- /dev/null +++ b/config/auth.ts @@ -0,0 +1,263 @@ +/** + * Config source: https://git.io/JY0mp + * + * Feel free to let us know via PR, if you find something broken in this config + * file. + */ + +import { AuthConfig } from '@ioc:Adonis/Addons/Auth'; +import Env from '@ioc:Adonis/Core/Env'; +import { appKey, jwtUsePEM } from './app'; + +/* +|-------------------------------------------------------------------------- +| Authentication Mapping +|-------------------------------------------------------------------------- +| +| List of available authentication mapping. You must first define them +| inside the `contracts/auth.ts` file before mentioning them here. +| +*/ +const authConfig: AuthConfig = { + guard: 'web', + guards: { + /* + |-------------------------------------------------------------------------- + | Web Guard + |-------------------------------------------------------------------------- + | + | Web guard uses classic old school sessions for authenticating users. + | If you are building a standard web application, it is recommended to + | use web guard with session driver + | + */ + web: { + driver: 'session', + + provider: { + /* + |-------------------------------------------------------------------------- + | Driver + |-------------------------------------------------------------------------- + | + | Name of the driver + | + */ + driver: 'lucid', + + /* + |-------------------------------------------------------------------------- + | Identifier key + |-------------------------------------------------------------------------- + | + | The identifier key is the unique key on the model. In most cases specifying + | the primary key is the right choice. + | + */ + identifierKey: 'id', + + /* + |-------------------------------------------------------------------------- + | Uids + |-------------------------------------------------------------------------- + | + | Uids are used to search a user against one of the mentioned columns. During + | login, the auth module will search the user mentioned value against one + | of the mentioned columns to find their user record. + | + */ + uids: ['email'], + + /* + |-------------------------------------------------------------------------- + | Model + |-------------------------------------------------------------------------- + | + | The model to use for fetching or finding users. The model is imported + | lazily since the config files are read way earlier in the lifecycle + | of booting the app and the models may not be in a usable state at + | that time. + | + */ + model: () => import('App/Models/User'), + }, + }, + /* + |-------------------------------------------------------------------------- + | OAT Guard + |-------------------------------------------------------------------------- + | + | OAT (Opaque access tokens) guard uses database backed tokens to authenticate + | HTTP request. This guard DOES NOT rely on sessions or cookies and uses + | Authorization header value for authentication. + | + | Use this guard to authenticate mobile apps or web clients that cannot rely + | on cookies/sessions. + | + */ + api: { + driver: 'oat', + + /* + |-------------------------------------------------------------------------- + | Tokens provider + |-------------------------------------------------------------------------- + | + | Uses SQL database for managing tokens. Use the "database" driver, when + | tokens are the secondary mode of authentication. + | For example: The Github personal tokens + | + | The foreignKey column is used to make the relationship between the user + | and the token. You are free to use any column name here. + | + */ + tokenProvider: { + type: 'api', + driver: 'database', + table: 'tokens', + foreignKey: 'user_id', + }, + + provider: { + /* + |-------------------------------------------------------------------------- + | Driver + |-------------------------------------------------------------------------- + | + | Name of the driver + | + */ + driver: 'lucid', + + /* + |-------------------------------------------------------------------------- + | Identifier key + |-------------------------------------------------------------------------- + | + | The identifier key is the unique key on the model. In most cases specifying + | the primary key is the right choice. + | + */ + identifierKey: 'id', + + /* + |-------------------------------------------------------------------------- + | Uids + |-------------------------------------------------------------------------- + | + | Uids are used to search a user against one of the mentioned columns. During + | login, the auth module will search the user mentioned value against one + | of the mentioned columns to find their user record. + | + */ + uids: ['email'], + + /* + |-------------------------------------------------------------------------- + | Model + |-------------------------------------------------------------------------- + | + | The model to use for fetching or finding users. The model is imported + | lazily since the config files are read way earlier in the lifecycle + | of booting the app and the models may not be in a usable state at + | that time. + | + */ + model: () => import('App/Models/User'), + }, + }, + /* + |-------------------------------------------------------------------------- + | Basic Auth Guard + |-------------------------------------------------------------------------- + | + | Uses Basic auth to authenticate an HTTP request. There is no concept of + | "login" and "logout" with basic auth. You just authenticate the requests + | using a middleware and browser will prompt the user to enter their login + | details + | + */ + basic: { + driver: 'basic', + realm: 'Login', + + provider: { + /* + |-------------------------------------------------------------------------- + | Driver + |-------------------------------------------------------------------------- + | + | Name of the driver + | + */ + driver: 'lucid', + + /* + |-------------------------------------------------------------------------- + | Identifier key + |-------------------------------------------------------------------------- + | + | The identifier key is the unique key on the model. In most cases specifying + | the primary key is the right choice. + | + */ + identifierKey: 'id', + + /* + |-------------------------------------------------------------------------- + | Uids + |-------------------------------------------------------------------------- + | + | Uids are used to search a user against one of the mentioned columns. During + | login, the auth module will search the user mentioned value against one + | of the mentioned columns to find their user record. + | + */ + uids: ['email'], + + /* + |-------------------------------------------------------------------------- + | Model + |-------------------------------------------------------------------------- + | + | The model to use for fetching or finding users. The model is imported + | lazily since the config files are read way earlier in the lifecycle + | of booting the app and the models may not be in a usable state at + | that time. + | + */ + model: () => import('App/Models/User'), + }, + }, + jwt: { + driver: 'jwt', + secret: jwtUsePEM ? undefined : appKey, + algorithmJwt: jwtUsePEM ? undefined : 'HS256', + publicKey: jwtUsePEM + ? Env.get('JWT_PUBLIC_KEY', '').replaceAll('\\n', '\n') + : undefined, + privateKey: jwtUsePEM + ? Env.get('JWT_PRIVATE_KEY', '').replaceAll('\\n', '\n') + : undefined, + persistJwt: true, + // TODO: We should improve the following implementation as this is a security concern. + // The following ts-expect-error is to set exp to undefined (JWT with no expiration) + // @ts-expect-error + jwtDefaultExpire: undefined, + refreshTokenDefaultExpire: '10d', + tokenProvider: { + driver: 'database', + table: 'jwt_tokens', + foreignKey: 'user_id', + }, + provider: { + driver: 'lucid', + identifierKey: 'id', + uids: [], + model: () => import('App/Models/User'), + }, + }, + }, +}; + +export default authConfig; diff --git a/config/bodyParser.js b/config/bodyParser.js deleted file mode 100644 index c336e67..0000000 --- a/config/bodyParser.js +++ /dev/null @@ -1,156 +0,0 @@ - -module.exports = { - /* - |-------------------------------------------------------------------------- - | JSON Parser - |-------------------------------------------------------------------------- - | - | Below settings are applied when the request body contains a JSON payload. - | If you want body parser to ignore JSON payloads, then simply set `types` - | to an empty array. - */ - json: { - /* - |-------------------------------------------------------------------------- - | limit - |-------------------------------------------------------------------------- - | - | Defines the limit of JSON that can be sent by the client. If payload - | is over 1mb it will not be processed. - | - */ - limit: '50mb', - - /* - |-------------------------------------------------------------------------- - | strict - |-------------------------------------------------------------------------- - | - | When `strict` is set to true, body parser will only parse Arrays and - | Object. Otherwise everything parseable by `JSON.parse` is parsed. - | - */ - strict: true, - - /* - |-------------------------------------------------------------------------- - | types - |-------------------------------------------------------------------------- - | - | Which content types are processed as JSON payloads. You are free to - | add your own types here, but the request body should be parseable - | by `JSON.parse` method. - | - */ - types: [ - 'application/json', - 'application/json-patch+json', - 'application/vnd.api+json', - 'application/csp-report', - ], - }, - - /* - |-------------------------------------------------------------------------- - | Raw Parser - |-------------------------------------------------------------------------- - | - | - | - */ - raw: { - types: [ - 'text/*', - ], - }, - - /* - |-------------------------------------------------------------------------- - | Form Parser - |-------------------------------------------------------------------------- - | - | - | - */ - form: { - types: [ - 'application/x-www-form-urlencoded', - ], - }, - - /* - |-------------------------------------------------------------------------- - | Files Parser - |-------------------------------------------------------------------------- - | - | - | - */ - files: { - types: [ - 'multipart/form-data', - ], - - /* - |-------------------------------------------------------------------------- - | Max Size - |-------------------------------------------------------------------------- - | - | Below value is the max size of all the files uploaded to the server. It - | is validated even before files have been processed and hard exception - | is thrown. - | - | Consider setting a reasonable value here, otherwise people may upload GB's - | of files which will keep your server busy. - | - | Also this value is considered when `autoProcess` is set to true. - | - */ - maxSize: '20mb', - - /* - |-------------------------------------------------------------------------- - | Auto Process - |-------------------------------------------------------------------------- - | - | Whether or not to auto-process files. Since HTTP servers handle files via - | couple of specific endpoints. It is better to set this value off and - | manually process the files when required. - | - | This value can contain a boolean or an array of route patterns - | to be autoprocessed. - */ - autoProcess: true, - - /* - |-------------------------------------------------------------------------- - | Process Manually - |-------------------------------------------------------------------------- - | - | The list of routes that should not process files and instead rely on - | manual process. This list should only contain routes when autoProcess - | is to true. Otherwise everything is processed manually. - | - */ - processManually: [], - - /* - |-------------------------------------------------------------------------- - | Temporary file name - |-------------------------------------------------------------------------- - | - | Define a function, which should return a string to be used as the - | tmp file name. - | - | If not defined, Bodyparser will use `uuid` as the tmp file name. - | - | To be defined as. If you are defining the function, then do make sure - | to return a value from it. - | - | tmpFileName () { - | return 'some-unique-value' - | } - | - */ - }, -}; diff --git a/config/bodyparser.ts b/config/bodyparser.ts new file mode 100644 index 0000000..b5adcda --- /dev/null +++ b/config/bodyparser.ts @@ -0,0 +1,205 @@ +/** + * Config source: https://git.io/Jfefn + * + * Feel free to let us know via PR, if you find something broken in this config + * file. + */ + +import { BodyParserConfig } from '@ioc:Adonis/Core/BodyParser'; + +const bodyParserConfig: BodyParserConfig = { + /* + |-------------------------------------------------------------------------- + | White listed methods + |-------------------------------------------------------------------------- + | + | HTTP methods for which body parsing must be performed. It is a good practice + | to avoid body parsing for `GET` requests. + | + */ + whitelistedMethods: ['POST', 'PUT', 'PATCH', 'DELETE'], + + /* + |-------------------------------------------------------------------------- + | JSON parser settings + |-------------------------------------------------------------------------- + | + | The settings for the JSON parser. The types defines the request content + | types which gets processed by the JSON parser. + | + */ + json: { + encoding: 'utf8', + limit: '1mb', + strict: true, + types: [ + 'application/json', + 'application/json-patch+json', + 'application/vnd.api+json', + 'application/csp-report', + ], + }, + + /* + |-------------------------------------------------------------------------- + | Form parser settings + |-------------------------------------------------------------------------- + | + | The settings for the `application/x-www-form-urlencoded` parser. The types + | defines the request content types which gets processed by the form parser. + | + */ + form: { + encoding: 'utf8', + limit: '1mb', + queryString: {}, + + /* + |-------------------------------------------------------------------------- + | Convert empty strings to null + |-------------------------------------------------------------------------- + | + | Convert empty form fields to null. HTML forms results in field string + | value when the field is left blank. This option normalizes all the blank + | field values to "null" + | + */ + convertEmptyStringsToNull: true, + + types: ['application/x-www-form-urlencoded'], + }, + + /* + |-------------------------------------------------------------------------- + | Raw body parser settings + |-------------------------------------------------------------------------- + | + | Raw body just reads the request body stream as a plain text, which you + | can process by hand. This must be used when request body type is not + | supported by the body parser. + | + */ + raw: { + encoding: 'utf8', + limit: '1mb', + queryString: {}, + types: ['text/*'], + }, + + /* + |-------------------------------------------------------------------------- + | Multipart parser settings + |-------------------------------------------------------------------------- + | + | The settings for the `multipart/form-data` parser. The types defines the + | request content types which gets processed by the form parser. + | + */ + multipart: { + /* + |-------------------------------------------------------------------------- + | Auto process + |-------------------------------------------------------------------------- + | + | The auto process option will process uploaded files and writes them to + | the `tmp` folder. You can turn it off and then manually use the stream + | to pipe stream to a different destination. + | + | It is recommended to keep `autoProcess=true`. Unless you are processing bigger + | file sizes. + | + */ + autoProcess: true, + + /* + |-------------------------------------------------------------------------- + | Files to be processed manually + |-------------------------------------------------------------------------- + | + | You can turn off `autoProcess` for certain routes by defining + | routes inside the following array. + | + | NOTE: Make sure the route pattern starts with a leading slash. + | + | Correct + | ```js + | /projects/:id/file + | ``` + | + | Incorrect + | ```js + | projects/:id/file + | ``` + */ + processManually: [], + + /* + |-------------------------------------------------------------------------- + | Temporary file name + |-------------------------------------------------------------------------- + | + | When auto processing is on. We will use this method to compute the temporary + | file name. AdonisJs will compute a unique `tmpPath` for you automatically, + | However, you can also define your own custom method. + | + */ + // tmpFileName () { + // }, + + /* + |-------------------------------------------------------------------------- + | Encoding + |-------------------------------------------------------------------------- + | + | Request body encoding + | + */ + encoding: 'utf8', + + /* + |-------------------------------------------------------------------------- + | Convert empty strings to null + |-------------------------------------------------------------------------- + | + | Convert empty form fields to null. HTML forms results in field string + | value when the field is left blank. This option normalizes all the blank + | field values to "null" + | + */ + convertEmptyStringsToNull: true, + + /* + |-------------------------------------------------------------------------- + | Max Fields + |-------------------------------------------------------------------------- + | + | The maximum number of fields allowed in the request body. The field includes + | text inputs and files both. + | + */ + maxFields: 1000, + + /* + |-------------------------------------------------------------------------- + | Request body limit + |-------------------------------------------------------------------------- + | + | The total limit to the multipart body. This includes all request files + | and fields data. + | + */ + limit: '20mb', + + /* + |-------------------------------------------------------------------------- + | Types + |-------------------------------------------------------------------------- + | + | The types that will be considered and parsed as multipart body. + | + */ + types: ['multipart/form-data'], + }, +}; + +export default bodyParserConfig; diff --git a/config/cors.js b/config/cors.js deleted file mode 100644 index 7ebbe3f..0000000 --- a/config/cors.js +++ /dev/null @@ -1,86 +0,0 @@ - -module.exports = { - /* - |-------------------------------------------------------------------------- - | Origin - |-------------------------------------------------------------------------- - | - | Set a list of origins to be allowed. The value can be one of the following - | - | Boolean: true - Allow current request origin - | Boolean: false - Disallow all - | String - Comma separated list of allowed origins - | Array - An array of allowed origins - | String: * - A wildcard to allow current request origin - | Function - Receives the current origin and should return one of the above values. - | - */ - origin: false, - - /* - |-------------------------------------------------------------------------- - | Methods - |-------------------------------------------------------------------------- - | - | HTTP methods to be allowed. The value can be one of the following - | - | String - Comma separated list of allowed methods - | Array - An array of allowed methods - | - */ - methods: ['GET', 'PUT', 'PATCH', 'POST', 'DELETE'], - - /* - |-------------------------------------------------------------------------- - | Headers - |-------------------------------------------------------------------------- - | - | List of headers to be allowed via Access-Control-Request-Headers header. - | The value can be one of the following. - | - | Boolean: true - Allow current request headers - | Boolean: false - Disallow all - | String - Comma separated list of allowed headers - | Array - An array of allowed headers - | String: * - A wildcard to allow current request headers - | Function - Receives the current header and should return one of the above values. - | - */ - headers: true, - - /* - |-------------------------------------------------------------------------- - | Expose Headers - |-------------------------------------------------------------------------- - | - | A list of headers to be exposed via `Access-Control-Expose-Headers` - | header. The value can be one of the following. - | - | Boolean: false - Disallow all - | String: Comma separated list of allowed headers - | Array - An array of allowed headers - | - */ - exposeHeaders: false, - - /* - |-------------------------------------------------------------------------- - | Credentials - |-------------------------------------------------------------------------- - | - | Define Access-Control-Allow-Credentials header. It should always be a - | boolean. - | - */ - credentials: false, - - /* - |-------------------------------------------------------------------------- - | MaxAge - |-------------------------------------------------------------------------- - | - | Define Access-Control-Allow-Max-Age - | - */ - maxAge: 90, -}; diff --git a/config/cors.ts b/config/cors.ts new file mode 100644 index 0000000..dc0e3f6 --- /dev/null +++ b/config/cors.ts @@ -0,0 +1,134 @@ +/** + * Config source: https://git.io/JfefC + * + * Feel free to let us know via PR, if you find something broken in this config + * file. + */ + +import { CorsConfig } from '@ioc:Adonis/Core/Cors'; + +const corsConfig: CorsConfig = { + /* + |-------------------------------------------------------------------------- + | Enabled + |-------------------------------------------------------------------------- + | + | A boolean to enable or disable CORS integration from your AdonisJs + | application. + | + | Setting the value to `true` will enable the CORS for all HTTP request. However, + | you can define a function to enable/disable it on per request basis as well. + | + */ + enabled: false, + + // You can also use a function that return true or false. + // enabled: (request) => request.url().startsWith('/api') + + /* + |-------------------------------------------------------------------------- + | Origin + |-------------------------------------------------------------------------- + | + | Set a list of origins to be allowed for `Access-Control-Allow-Origin`. + | The value can be one of the following: + | + | https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin + | + | Boolean (true) - Allow current request origin. + | Boolean (false) - Disallow all. + | String - Comma separated list of allowed origins. + | Array - An array of allowed origins. + | String (*) - A wildcard (*) to allow all request origins. + | Function - Receives the current origin string and should return + | one of the above values. + | + */ + origin: true, + + /* + |-------------------------------------------------------------------------- + | Methods + |-------------------------------------------------------------------------- + | + | An array of allowed HTTP methods for CORS. The `Access-Control-Request-Method` + | is checked against the following list. + | + | Following is the list of default methods. Feel free to add more. + */ + methods: ['GET', 'HEAD', 'POST', 'PUT', 'DELETE'], + + /* + |-------------------------------------------------------------------------- + | Headers + |-------------------------------------------------------------------------- + | + | List of headers to be allowed for `Access-Control-Allow-Headers` header. + | The value can be one of the following: + | + | https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Headers + | + | Boolean(true) - Allow all headers mentioned in `Access-Control-Request-Headers`. + | Boolean(false) - Disallow all headers. + | String - Comma separated list of allowed headers. + | Array - An array of allowed headers. + | Function - Receives the current header and should return one of the above values. + | + */ + headers: true, + + /* + |-------------------------------------------------------------------------- + | Expose Headers + |-------------------------------------------------------------------------- + | + | A list of headers to be exposed by setting `Access-Control-Expose-Headers`. + | header. By default following 6 simple response headers are exposed. + | + | Cache-Control + | Content-Language + | Content-Type + | Expires + | Last-Modified + | Pragma + | + | In order to add more headers, simply define them inside the following array. + | + | https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers + | + */ + exposeHeaders: [ + 'cache-control', + 'content-language', + 'content-type', + 'expires', + 'last-modified', + 'pragma', + ], + + /* + |-------------------------------------------------------------------------- + | Credentials + |-------------------------------------------------------------------------- + | + | Toggle `Access-Control-Allow-Credentials` header. If value is set to `true`, + | then header will be set, otherwise not. + | + | https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials + | + */ + credentials: true, + + /* + |-------------------------------------------------------------------------- + | MaxAge + |-------------------------------------------------------------------------- + | + | Define `Access-Control-Max-Age` header in seconds. + | https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age + | + */ + maxAge: 90, +}; + +export default corsConfig; diff --git a/config/dashboard.ts b/config/dashboard.ts new file mode 100644 index 0000000..18feb14 --- /dev/null +++ b/config/dashboard.ts @@ -0,0 +1,5 @@ +import Env from '@ioc:Adonis/Core/Env'; + +export const enabled: boolean = Env.get('IS_DASHBOARD_ENABLED') !== 'false'; + +export const mailFrom: string = Env.get('MAIL_SENDER'); diff --git a/config/database.js b/config/database.js deleted file mode 100644 index 5c51996..0000000 --- a/config/database.js +++ /dev/null @@ -1,88 +0,0 @@ -const path = require("path"); - -/** @type {import('@adonisjs/framework/src/Env')} */ -const Env = use('Env'); - -/** @type {import('@adonisjs/ignitor/src/Helpers')} */ -const Helpers = use('Helpers'); - -module.exports = { - /* - |-------------------------------------------------------------------------- - | Default Connection - |-------------------------------------------------------------------------- - | - | Connection defines the default connection settings to be used while - | interacting with SQL databases. - | - */ - connection: Env.get('DB_CONNECTION', 'sqlite'), - - /* - |-------------------------------------------------------------------------- - | Sqlite - |-------------------------------------------------------------------------- - | - | Sqlite is a flat file database and can be a good choice for a development - | environment. - | - | npm i --save sqlite3 - | - */ - sqlite: { - client: 'sqlite3', - connection: { - filename: path.join(Env.get('DATA_DIR', 'data'), `${Env.get('DB_DATABASE', 'ferdium')}.sqlite`), - }, - useNullAsDefault: true, - debug: Env.get('DB_DEBUG', false), - }, - - /* - |-------------------------------------------------------------------------- - | MySQL - |-------------------------------------------------------------------------- - | - | Here we define connection settings for MySQL database. - | - | npm i --save mysql - | - */ - mysql: { - client: 'mysql', - connection: { - host: Env.get('DB_HOST', 'localhost'), - port: Env.get('DB_PORT', ''), - user: Env.get('DB_USER', 'root'), - password: Env.get('DB_PASSWORD', ''), - database: Env.get('DB_DATABASE', 'ferdium'), - }, - debug: Env.get('DB_DEBUG', false), - }, - - /* - |-------------------------------------------------------------------------- - | PostgreSQL - |-------------------------------------------------------------------------- - | - | Here we define connection settings for PostgreSQL database. - | - | npm i --save pg - | - */ - pg: { - client: 'pg', - connection: { - host: Env.get('DB_HOST', 'localhost'), - port: Env.get('DB_PORT', ''), - user: Env.get('DB_USER', 'root'), - password: Env.get('DB_PASSWORD', ''), - database: Env.get('DB_DATABASE', 'ferdium'), - ssl: Env.get('DB_CA_CERT') ? { - rejectUnauthorized: false, - ca: Env.get('DB_CA_CERT'), - } : JSON.parse(Env.get('DB_SSL', 'true')), - }, - debug: Env.get('DB_DEBUG', false), - }, -}; diff --git a/config/database.ts b/config/database.ts new file mode 100644 index 0000000..65a9455 --- /dev/null +++ b/config/database.ts @@ -0,0 +1,121 @@ +/* eslint-disable @typescript-eslint/indent */ +/** + * Config source: https://git.io/JesV9 + * + * Feel free to let us know via PR, if you find something broken in this config + * file. + */ + +import path from 'node:path'; +import Env from '@ioc:Adonis/Core/Env'; +import { DatabaseConfig } from '@ioc:Adonis/Lucid/Database'; + +const databaseConfig: DatabaseConfig = { + /* + |-------------------------------------------------------------------------- + | Connection + |-------------------------------------------------------------------------- + | + | The primary connection for making database queries across the application + | You can use any key from the `connections` object defined in this same + | file. + | + */ + connection: Env.get('DB_CONNECTION', 'sqlite'), + + connections: { + /* + |-------------------------------------------------------------------------- + | SQLite + |-------------------------------------------------------------------------- + | + | Configuration for the SQLite database. Make sure to install the driver + | from npm when using this connection + | + | npm i sqlite3 + | + */ + sqlite: { + client: 'sqlite', + connection: { + filename: path.join( + Env.get('DATA_DIR', 'data'), + `${Env.get('DB_DATABASE', 'ferdium')}.sqlite`, + ), + }, + pool: { + afterCreate: (conn, cb) => { + conn.run('PRAGMA foreign_keys=true', cb); + }, + }, + migrations: { + naturalSort: true, + }, + useNullAsDefault: true, + healthCheck: false, + debug: Env.get('DB_DEBUG', false), + }, + + /* + |-------------------------------------------------------------------------- + | MySQL config + |-------------------------------------------------------------------------- + | + | Configuration for MySQL database. Make sure to install the driver + | from npm when using this connection + | + | npm i mysql + | + */ + mysql: { + client: 'mysql', + connection: { + host: Env.get('DB_HOST', 'localhost'), + port: Env.get('DB_PORT', ''), + user: Env.get('DB_USER', 'root'), + password: Env.get('DB_PASSWORD', ''), + database: Env.get('DB_DATABASE', 'ferdium'), + }, + migrations: { + naturalSort: true, + }, + healthCheck: false, + debug: Env.get('DB_DEBUG', false), + }, + + /* + |-------------------------------------------------------------------------- + | PostgreSQL config + |-------------------------------------------------------------------------- + | + | Configuration for PostgreSQL database. Make sure to install the driver + | from npm when using this connection + | + | npm i pg + | + */ + pg: { + client: 'pg', + connection: { + host: Env.get('DB_HOST', 'localhost'), + port: Env.get('DB_PORT', ''), + user: Env.get('DB_USER', 'root'), + password: Env.get('DB_PASSWORD', ''), + database: Env.get('DB_DATABASE', 'ferdium'), + ssl: Env.get('DB_CA_CERT') + ? { + rejectUnauthorized: false, + ca: Env.get('DB_CA_CERT'), + } + : JSON.parse(Env.get('DB_SSL', 'true')), + }, + migrations: { + naturalSort: true, + }, + healthCheck: false, + debug: Env.get('DB_DEBUG', false), + }, + }, +}; + +export default databaseConfig; diff --git a/config/drive.js b/config/drive.js deleted file mode 100644 index cb4b2b3..0000000 --- a/config/drive.js +++ /dev/null @@ -1,45 +0,0 @@ -const Env = use('Env'); - -module.exports = { - /* - |-------------------------------------------------------------------------- - | Default disk - |-------------------------------------------------------------------------- - | - | The default disk is used when you interact with the file system without - | defining a disk name - | - */ - default: 'local', - - disks: { - /* - |-------------------------------------------------------------------------- - | Local - |-------------------------------------------------------------------------- - | - | Local disk interacts with the a local folder inside your application - | - */ - local: { - root: `${__dirname}/../recipes/archives`, - driver: 'local', - }, - - /* - |-------------------------------------------------------------------------- - | S3 - |-------------------------------------------------------------------------- - | - | S3 disk interacts with a bucket on aws s3 - | - */ - s3: { - driver: 's3', - key: Env.get('S3_KEY'), - secret: Env.get('S3_SECRET'), - bucket: Env.get('S3_BUCKET'), - region: Env.get('S3_REGION'), - }, - }, -}; diff --git a/config/drive.ts b/config/drive.ts new file mode 100644 index 0000000..b6950eb --- /dev/null +++ b/config/drive.ts @@ -0,0 +1,149 @@ +/** + * Config source: https://git.io/JBt3o + * + * Feel free to let us know via PR, if you find something broken in this config + * file. + */ + +import Env from '@ioc:Adonis/Core/Env'; +import { driveConfig } from '@adonisjs/core/build/config'; +import Application from '@ioc:Adonis/Core/Application'; + +/* +|-------------------------------------------------------------------------- +| Drive Config +|-------------------------------------------------------------------------- +| +| The `DriveConfig` relies on the `DisksList` interface which is +| defined inside the `contracts` directory. +| +*/ +export default driveConfig({ + /* + |-------------------------------------------------------------------------- + | Default disk + |-------------------------------------------------------------------------- + | + | The default disk to use for managing file uploads. The value is driven by + | the `DRIVE_DISK` environment variable. + | + */ + disk: Env.get('DRIVE_DISK', 'local'), + + disks: { + /* + |-------------------------------------------------------------------------- + | Local + |-------------------------------------------------------------------------- + | + | Uses the local file system to manage files. Make sure to turn off serving + | files when not using this disk. + | + */ + local: { + driver: 'local', + visibility: 'public', + + /* + |-------------------------------------------------------------------------- + | Storage root - Local driver only + |-------------------------------------------------------------------------- + | + | Define an absolute path to the storage directory from where to read the + | files. + | + */ + root: Application.tmpPath('uploads'), + + /* + |-------------------------------------------------------------------------- + | Serve files - Local driver only + |-------------------------------------------------------------------------- + | + | When this is set to true, AdonisJS will configure a files server to serve + | files from the disk root. This is done to mimic the behavior of cloud + | storage services that has inbuilt capabilities to serve files. + | + */ + serveFiles: true, + + /* + |-------------------------------------------------------------------------- + | Base path - Local driver only + |-------------------------------------------------------------------------- + | + | Base path is always required when "serveFiles = true". Also make sure + | the `basePath` is unique across all the disks using "local" driver and + | you are not registering routes with this prefix. + | + */ + basePath: '/uploads', + }, + + /* + |-------------------------------------------------------------------------- + | S3 Driver + |-------------------------------------------------------------------------- + | + | Uses the S3 cloud storage to manage files. Make sure to install the s3 + | drive separately when using it. + | + |************************************************************************** + | npm i @adonisjs/drive-s3 + |************************************************************************** + | + */ + // s3: { + // driver: 's3', + // visibility: 'public', + // key: Env.get('S3_KEY'), + // secret: Env.get('S3_SECRET'), + // region: Env.get('S3_REGION'), + // bucket: Env.get('S3_BUCKET'), + // endpoint: Env.get('S3_ENDPOINT'), + // + // // For minio to work + // // forcePathStyle: true, + // }, + + /* + |-------------------------------------------------------------------------- + | GCS Driver + |-------------------------------------------------------------------------- + | + | Uses the Google cloud storage to manage files. Make sure to install the GCS + | drive separately when using it. + | + |************************************************************************** + | npm i @adonisjs/drive-gcs + |************************************************************************** + | + */ + // gcs: { + // driver: 'gcs', + // visibility: 'public', + // keyFilename: Env.get('GCS_KEY_FILENAME'), + // bucket: Env.get('GCS_BUCKET'), + + /* + |-------------------------------------------------------------------------- + | Uniform ACL - Google cloud storage only + |-------------------------------------------------------------------------- + | + | When using the Uniform ACL on the bucket, the "visibility" option is + | ignored. Since, the files ACL is managed by the google bucket policies + | directly. + | + |************************************************************************** + | Learn more: https://cloud.google.com/storage/docs/uniform-bucket-level-access + |************************************************************************** + | + | The following option just informs drive whether your bucket is using uniform + | ACL or not. The actual setting needs to be toggled within the Google cloud + | console. + | + */ + // usingUniformAcl: false, + // }, + }, +}); diff --git a/config/hash.js b/config/hash.js deleted file mode 100644 index 297c977..0000000 --- a/config/hash.js +++ /dev/null @@ -1,48 +0,0 @@ - -/** @type {import('@adonisjs/framework/src/Env')} */ -const Env = use('Env'); - -module.exports = { - /* - |-------------------------------------------------------------------------- - | Driver - |-------------------------------------------------------------------------- - | - | Driver to be used for hashing values. The same driver is used by the - | auth module too. - | - */ - driver: Env.get('HASH_DRIVER', 'bcrypt'), - - /* - |-------------------------------------------------------------------------- - | Bcrypt - |-------------------------------------------------------------------------- - | - | Config related to bcrypt hashing. https://www.npmjs.com/package/bcrypt - | package is used internally. - | - */ - bcrypt: { - rounds: 10, - }, - - /* - |-------------------------------------------------------------------------- - | Argon - |-------------------------------------------------------------------------- - | - | Config related to argon. https://www.npmjs.com/package/argon2 package is - | used internally. - | - | Since argon is optional, you will have to install the dependency yourself - | - |============================================================================ - | npm i argon2 - |============================================================================ - | - */ - argon: { - type: 1, - }, -}; diff --git a/config/hash.ts b/config/hash.ts new file mode 100644 index 0000000..abe7dd0 --- /dev/null +++ b/config/hash.ts @@ -0,0 +1,88 @@ +/** + * Config source: https://git.io/JfefW + * + * Feel free to let us know via PR, if you find something broken in this config + * file. + */ + +import Env from '@ioc:Adonis/Core/Env'; +import { hashConfig } from '@adonisjs/core/build/config'; + +/* +|-------------------------------------------------------------------------- +| Hash Config +|-------------------------------------------------------------------------- +| +| The `HashConfig` relies on the `HashList` interface which is +| defined inside `contracts` directory. +| +*/ +export default hashConfig({ + /* + |-------------------------------------------------------------------------- + | Default hasher + |-------------------------------------------------------------------------- + | + | By default we make use of the argon hasher to hash values. However, feel + | free to change the default value + | + | Default is set to bcrypt to prevent breaking-changes. + */ + default: Env.get('HASH_DRIVER', 'scrypt'), + + list: { + scrypt: { + driver: 'scrypt', + cost: 16_384, + blockSize: 8, + parallelization: 1, + saltSize: 16, + keyLength: 64, + maxMemory: 32 * 1024 * 1024, + }, + /* + |-------------------------------------------------------------------------- + | Argon + |-------------------------------------------------------------------------- + | + | Argon mapping uses the `argon2` driver to hash values. + | + | Make sure you install the underlying dependency for this driver to work. + | https://www.npmjs.com/package/phc-argon2. + | + | npm install phc-argon2 + | + */ + argon: { + driver: 'argon2', + variant: 'id', + iterations: 3, + memory: 4096, + parallelism: 1, + saltSize: 16, + }, + + /* + |-------------------------------------------------------------------------- + | Bcrypt + |-------------------------------------------------------------------------- + | + | Bcrypt mapping uses the `bcrypt` driver to hash values. + | + | Make sure you install the underlying dependency for this driver to work. + | https://www.npmjs.com/package/phc-bcrypt. + | + | npm install phc-bcrypt + | + */ + bcrypt: { + driver: 'bcrypt', + rounds: 10, + }, + + legacy: { + // @ts-expect-error + driver: 'legacy', + }, + }, +}); diff --git a/config/mail.js b/config/mail.js deleted file mode 100644 index 8fb6356..0000000 --- a/config/mail.js +++ /dev/null @@ -1,104 +0,0 @@ -const Env = use('Env'); - -module.exports = { - /* - |-------------------------------------------------------------------------- - | Connection - |-------------------------------------------------------------------------- - | - | Connection to be used for sending emails. Each connection needs to - | define a driver too. - | - */ - connection: Env.get('MAIL_CONNECTION', 'smtp'), - - /* - |-------------------------------------------------------------------------- - | SMTP - |-------------------------------------------------------------------------- - | - | Here we define configuration for sending emails via SMTP. - | - | https://nodemailer.com/smtp/ - | - */ - smtp: { - driver: 'smtp', - pool: true, - name: Env.get('APP_URL'), - port: Env.get('SMTP_PORT', '2525'), - host: Env.get('SMTP_HOST', 'localhost'), - secure: JSON.parse(Env.get('MAIL_SSL', 'false')), - requireTLS: JSON.parse(Env.get('MAIL_REQUIRE_TLS', 'false')), - authMethod: 'LOGIN', - auth: { - user: Env.get('MAIL_USERNAME'), - pass: Env.get('MAIL_PASSWORD'), - }, - maxConnections: 5, - maxMessages: 100, - rateLimit: 10, - }, - - /* - |-------------------------------------------------------------------------- - | SparkPost - |-------------------------------------------------------------------------- - | - | Here we define configuration for spark post. Extra options can be defined - | inside the `extra` object. - | - | https://developer.sparkpost.com/api/transmissions.html#header-options-attributes - | - | extras: { - | campaign_id: 'sparkpost campaign id', - | options: { // sparkpost options } - | } - | - */ - sparkpost: { - driver: 'sparkpost', - apiKey: Env.get('SPARKPOST_API_KEY'), - extras: {}, - }, - - /* - |-------------------------------------------------------------------------- - | Mailgun - |-------------------------------------------------------------------------- - | - | Here we define configuration for mailgun. Extra options can be defined - | inside the `extra` object. - | - | https://mailgun-documentation.readthedocs.io/en/latest/api-sending.html#sending - | - | extras: { - | 'o:tag': '', - | 'o:campaign': '',, - | . . . - | } - | - */ - mailgun: { - driver: 'mailgun', - domain: Env.get('MAILGUN_DOMAIN'), - region: Env.get('MAILGUN_API_REGION'), - apiKey: Env.get('MAILGUN_API_KEY'), - extras: {}, - }, - - /* - |-------------------------------------------------------------------------- - | Ethereal - |-------------------------------------------------------------------------- - | - | Ethereal driver to quickly test emails in your browser. A disposable - | account is created automatically for you. - | - | https://ethereal.email - | - */ - ethereal: { - driver: 'ethereal', - }, -}; diff --git a/config/mail.ts b/config/mail.ts new file mode 100644 index 0000000..1210592 --- /dev/null +++ b/config/mail.ts @@ -0,0 +1,118 @@ +/** + * Config source: https://git.io/JvgAf + * + * Feel free to let us know via PR, if you find something broken in this contract + * file. + */ + +import Env from '@ioc:Adonis/Core/Env'; +import { mailConfig } from '@adonisjs/mail/build/config'; + +export default mailConfig({ + /* + |-------------------------------------------------------------------------- + | Default mailer + |-------------------------------------------------------------------------- + | + | The following mailer will be used to send emails, when you don't specify + | a mailer + | + */ + mailer: 'smtp', + + /* + |-------------------------------------------------------------------------- + | Mailers + |-------------------------------------------------------------------------- + | + | You can define or more mailers to send emails from your application. A + | single `driver` can be used to define multiple mailers with different + | config. + | + | For example: Postmark driver can be used to have different mailers for + | sending transactional and promotional emails + | + */ + mailers: { + /* + |-------------------------------------------------------------------------- + | Smtp + |-------------------------------------------------------------------------- + | + | Uses SMTP protocol for sending email + | + */ + smtp: { + driver: 'smtp', + name: Env.get('APP_URL'), + port: Env.get('SMTP_PORT', '2525'), + host: Env.get('SMTP_HOST', 'localhost'), + secure: JSON.parse(Env.get('MAIL_SSL', 'false')), + requireTLS: JSON.parse(Env.get('MAIL_REQUIRE_TLS', 'false')), + auth: { + user: Env.get('SMTP_USERNAME'), + pass: Env.get('SMTP_PASSWORD'), + type: 'login', + }, + maxConnections: 5, + maxMessages: 100, + rateLimit: 10, + }, + + /* + |-------------------------------------------------------------------------- + | SES + |-------------------------------------------------------------------------- + | + | Uses Amazon SES for sending emails. You will have to install the aws-sdk + | when using this driver. + | + | ``` + | npm i aws-sdk + | ``` + | + */ + ses: { + driver: 'ses', + apiVersion: '2010-12-01', + key: Env.get('SES_ACCESS_KEY'), + secret: Env.get('SES_ACCESS_SECRET'), + region: Env.get('SES_REGION'), + sslEnabled: true, + sendingRate: 10, + maxConnections: 5, + }, + + /* + |-------------------------------------------------------------------------- + | Mailgun + |-------------------------------------------------------------------------- + | + | Uses Mailgun service for sending emails. + | + | If you are using an EU domain. Ensure to change the baseUrl to hit the + | europe endpoint (https://api.eu.mailgun.net/v3). + | + */ + mailgun: { + driver: 'mailgun', + baseUrl: 'https://api.mailgun.net/v3', + key: Env.get('MAILGUN_API_KEY'), + domain: Env.get('MAILGUN_DOMAIN'), + }, + + /* + |-------------------------------------------------------------------------- + | SparkPost + |-------------------------------------------------------------------------- + | + | Uses Sparkpost service for sending emails. + | + */ + sparkpost: { + driver: 'sparkpost', + baseUrl: 'https://api.sparkpost.com/api/v1', + key: Env.get('SPARKPOST_API_KEY'), + }, + }, +}); diff --git a/config/persona.js b/config/persona.js deleted file mode 100644 index c259a06..0000000 --- a/config/persona.js +++ /dev/null @@ -1,94 +0,0 @@ -/* -|-------------------------------------------------------------------------- -| Persona -|-------------------------------------------------------------------------- -| -| The persona is a simple and opinionated service to register, login and -| manage user account -| -*/ - -module.exports = { - /* - |-------------------------------------------------------------------------- - | Uids - |-------------------------------------------------------------------------- - | - | An array of fields, that can be used to indetify a user uniquely. During - | login and reset password, these fields be checked against the user - | input - | - */ - uids: ['email'], - - /* - |-------------------------------------------------------------------------- - | Email field - |-------------------------------------------------------------------------- - | - | The name of the email field inside the database and the user payload. - | - */ - email: 'email', - - /* - |-------------------------------------------------------------------------- - | Password - |-------------------------------------------------------------------------- - | - | The password field to be used for verifying and storing user password - | - */ - password: 'password', - - /* - |-------------------------------------------------------------------------- - | New account state - |-------------------------------------------------------------------------- - | - | State of user when a new account is created - | - */ - newAccountState: 'pending', - - /* - |-------------------------------------------------------------------------- - | Verified account state - |-------------------------------------------------------------------------- - | - | State of user after they verify their email address - | - */ - verifiedAccountState: 'active', - - /* - |-------------------------------------------------------------------------- - | Model - |-------------------------------------------------------------------------- - | - | The model to be used for verifying and creating users - | - */ - model: 'App/Models/User', - - /* - |-------------------------------------------------------------------------- - | Date Format - |-------------------------------------------------------------------------- - | - | The date format for the tokens table. It is required to calculate the - | expiry of a token. - | - */ - dateFormat: 'YYYY-MM-DD HH:mm:ss', - - /* - |-------------------------------------------------------------------------- - | Validation messages - |-------------------------------------------------------------------------- - | - | An object of validation messages to be used when validation fails. - | - */ - validationMessages: () => ({}), -}; diff --git a/config/session.js b/config/session.js deleted file mode 100644 index b2174da..0000000 --- a/config/session.js +++ /dev/null @@ -1,98 +0,0 @@ - -const Env = use('Env'); - -module.exports = { - /* - |-------------------------------------------------------------------------- - | Session Driver - |-------------------------------------------------------------------------- - | - | The session driver to be used for storing session values. It can be - | cookie, file or redis. - | - | For `redis` driver, make sure to install and register `@adonisjs/redis` - | - */ - driver: Env.get('SESSION_DRIVER', 'cookie'), - - /* - |-------------------------------------------------------------------------- - | Cookie Name - |-------------------------------------------------------------------------- - | - | The name of the cookie to be used for saving session id. Session ids - | are signed and encrypted. - | - */ - cookieName: 'adonis-session', - - /* - |-------------------------------------------------------------------------- - | Clear session when browser closes - |-------------------------------------------------------------------------- - | - | If this value is true, the session cookie will be temporary and will be - | removed when browser closes. - | - */ - clearWithBrowser: true, - - /* - |-------------------------------------------------------------------------- - | Session age - |-------------------------------------------------------------------------- - | - | This value is only used when `clearWithBrowser` is set to false. The - | age must be a valid https://npmjs.org/package/ms string or should - | be in milliseconds. - | - | Valid values are: - | '2h', '10d', '5y', '2.5 hrs' - | - */ - age: '2h', - - /* - |-------------------------------------------------------------------------- - | Cookie options - |-------------------------------------------------------------------------- - | - | Cookie options defines the options to be used for setting up session - | cookie - | - */ - cookie: { - httpOnly: true, - path: '/', - sameSite: true, - }, - - /* - |-------------------------------------------------------------------------- - | Sessions location - |-------------------------------------------------------------------------- - | - | If driver is set to file, we need to define the relative location from - | the temporary path or absolute url to any location. - | - */ - file: { - location: 'sessions', - }, - - /* - |-------------------------------------------------------------------------- - | Redis config - |-------------------------------------------------------------------------- - | - | The configuration for the redis driver. - | - */ - redis: { - host: '127.0.0.1', - port: 6379, - password: null, - db: 0, - keyPrefix: '', - }, -}; diff --git a/config/session.ts b/config/session.ts new file mode 100644 index 0000000..fbf8c7c --- /dev/null +++ b/config/session.ts @@ -0,0 +1,116 @@ +/** + * Config source: https://git.io/JeYHp + * + * Feel free to let us know via PR, if you find something broken in this config + * file. + */ + +import Env from '@ioc:Adonis/Core/Env'; +import Application from '@ioc:Adonis/Core/Application'; +import { sessionConfig } from '@adonisjs/session/build/config'; + +export default sessionConfig({ + /* + |-------------------------------------------------------------------------- + | Enable/Disable sessions + |-------------------------------------------------------------------------- + | + | Setting the following property to "false" will disable the session for the + | entire application + | + */ + enabled: true, + + /* + |-------------------------------------------------------------------------- + | Driver + |-------------------------------------------------------------------------- + | + | The session driver to use. You can choose between one of the following + | drivers. + | + | - cookie (Uses signed cookies to store session values) + | - file (Uses filesystem to store session values) + | - redis (Uses redis. Make sure to install "@adonisjs/redis" as well) + | + | Note: Switching drivers will make existing sessions invalid. + | + */ + driver: Env.get('SESSION_DRIVER', 'cookie'), + + /* + |-------------------------------------------------------------------------- + | Cookie name + |-------------------------------------------------------------------------- + | + | The name of the cookie that will hold the session id. + | + */ + cookieName: 'adonis-session', + + /* + |-------------------------------------------------------------------------- + | Clear session when browser closes + |-------------------------------------------------------------------------- + | + | Whether or not you want to destroy the session when browser closes. Setting + | this value to `true` will ignore the `age`. + | + */ + clearWithBrowser: true, + + /* + |-------------------------------------------------------------------------- + | Session age + |-------------------------------------------------------------------------- + | + | The duration for which session stays active after no activity. A new HTTP + | request to the server is considered as activity. + | + | The value can be a number in milliseconds or a string that must be valid + | as per https://npmjs.org/package/ms package. + | + | Example: `2 days`, `2.5 hrs`, `1y`, `5s` and so on. + | + */ + age: '2h', + + /* + |-------------------------------------------------------------------------- + | Cookie values + |-------------------------------------------------------------------------- + | + | The cookie settings are used to setup the session id cookie and also the + | driver will use the same values. + | + */ + cookie: { + path: '/', + httpOnly: true, + sameSite: false, + }, + + /* + |-------------------------------------------------------------------------- + | Configuration for the file driver + |-------------------------------------------------------------------------- + | + | The file driver needs absolute path to the directory in which sessions + | must be stored. + | + */ + file: { + location: Application.tmpPath('sessions'), + }, + + /* + |-------------------------------------------------------------------------- + | Redis driver + |-------------------------------------------------------------------------- + | + | The redis connection you want session driver to use. The same connection + | must be defined inside `config/redis.ts` file as well. + | + */ + redisConnection: 'local', +}); diff --git a/config/shield.js b/config/shield.js deleted file mode 100644 index 9849d29..0000000 --- a/config/shield.js +++ /dev/null @@ -1,144 +0,0 @@ - -module.exports = { - /* - |-------------------------------------------------------------------------- - | Content Security Policy - |-------------------------------------------------------------------------- - | - | Content security policy filters out the origins not allowed to execute - | and load resources like scripts, styles and fonts. There are wide - | variety of options to choose from. - */ - csp: { - /* - |-------------------------------------------------------------------------- - | Directives - |-------------------------------------------------------------------------- - | - | All directives are defined in camelCase and here is the list of - | available directives and their possible values. - | - | https://content-security-policy.com - | - | @example - | directives: { - | defaultSrc: ['self', '@nonce', 'cdnjs.cloudflare.com'] - | } - | - */ - directives: { - }, - /* - |-------------------------------------------------------------------------- - | Report only - |-------------------------------------------------------------------------- - | - | Setting `reportOnly=true` will not block the scripts from running and - | instead report them to a URL. - | - */ - reportOnly: false, - /* - |-------------------------------------------------------------------------- - | Set all headers - |-------------------------------------------------------------------------- - | - | Headers staring with `X` have been depreciated, since all major browsers - | supports the standard CSP header. So its better to disable deperciated - | headers, unless you want them to be set. - | - */ - setAllHeaders: false, - - /* - |-------------------------------------------------------------------------- - | Disable on android - |-------------------------------------------------------------------------- - | - | Certain versions of android are buggy with CSP policy. So you can set - | this value to true, to disable it for Android versions with buggy - | behavior. - | - | Here is an issue reported on a different package, but helpful to read - | if you want to know the behavior. https://github.com/helmetjs/helmet/pull/82 - | - */ - disableAndroid: true, - }, - - /* - |-------------------------------------------------------------------------- - | X-XSS-Protection - |-------------------------------------------------------------------------- - | - | X-XSS Protection saves from applications from XSS attacks. It is adopted - | by IE and later followed by some other browsers. - | - | Learn more at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-XSS-Protection - | - */ - xss: { - enabled: true, - enableOnOldIE: false, - }, - - /* - |-------------------------------------------------------------------------- - | Iframe Options - |-------------------------------------------------------------------------- - | - | xframe defines whether or not your website can be embedded inside an - | iframe. Choose from one of the following options. - | @available options - | DENY, SAMEORIGIN, ALLOW-FROM http://example.com - | - | Learn more at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options - */ - xframe: 'DENY', - - /* - |-------------------------------------------------------------------------- - | No Sniff - |-------------------------------------------------------------------------- - | - | Browsers have a habit of sniffing content-type of a response. Which means - | files with .txt extension containing Javascript code will be executed as - | Javascript. You can disable this behavior by setting nosniff to false. - | - | Learn more at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options - | - */ - nosniff: true, - - /* - |-------------------------------------------------------------------------- - | No Open - |-------------------------------------------------------------------------- - | - | IE users can execute webpages in the context of your website, which is - | a serious security risk. Below option will manage this for you. - | - */ - noopen: true, - - /* - |-------------------------------------------------------------------------- - | CSRF Protection - |-------------------------------------------------------------------------- - | - | CSRF Protection adds another layer of security by making sure, actionable - | routes does have a valid token to execute an action. - | - */ - csrf: { - enable: true, - methods: ['POST', 'PUT', 'DELETE'], - filterUris: [], - cookieOptions: { - httpOnly: true, - sameSite: true, - path: '/', - maxAge: 7200, - }, - }, -}; diff --git a/config/shield.ts b/config/shield.ts new file mode 100644 index 0000000..3566e1c --- /dev/null +++ b/config/shield.ts @@ -0,0 +1,243 @@ +/** + * Config source: https://git.io/Jvwvt + * + * Feel free to let us know via PR, if you find something broken in this config + * file. + */ + +import Env from '@ioc:Adonis/Core/Env'; +import { ShieldConfig } from '@ioc:Adonis/Addons/Shield'; + +/* +|-------------------------------------------------------------------------- +| Content Security Policy +|-------------------------------------------------------------------------- +| +| Content security policy filters out the origins not allowed to execute +| and load resources like scripts, styles and fonts. There are wide +| variety of options to choose from. +*/ +export const csp: ShieldConfig['csp'] = { + /* + |-------------------------------------------------------------------------- + | Enable/disable CSP + |-------------------------------------------------------------------------- + | + | The CSP rules are disabled by default for seamless onboarding. + | + */ + enabled: false, + + /* + |-------------------------------------------------------------------------- + | Directives + |-------------------------------------------------------------------------- + | + | All directives are defined in camelCase and here is the list of + | available directives and their possible values. + | + | https://content-security-policy.com + | + | @example + | directives: { + | defaultSrc: ["'self'", '@nonce', 'cdnjs.cloudflare.com'] + | } + | + */ + directives: {}, + + /* + |-------------------------------------------------------------------------- + | Report only + |-------------------------------------------------------------------------- + | + | Setting `reportOnly=true` will not block the scripts from running and + | instead report them to a URL. + | + */ + reportOnly: false, +}; + +/* +|-------------------------------------------------------------------------- +| CSRF Protection +|-------------------------------------------------------------------------- +| +| CSRF Protection adds another layer of security by making sure, actionable +| routes does have a valid token to execute an action. +| +*/ +export const csrf: ShieldConfig['csrf'] = { + /* + |-------------------------------------------------------------------------- + | Enable/Disable CSRF + |-------------------------------------------------------------------------- + */ + enabled: Env.get('NODE_ENV') === 'production', + + /* + |-------------------------------------------------------------------------- + | Routes to Ignore + |-------------------------------------------------------------------------- + | + | Define an array of route patterns that you want to ignore from CSRF + | validation. Make sure the route patterns are started with a leading + | slash. Example: + | + | `/foo/bar` + | + | Also you can define a function that is evaluated on every HTTP Request. + | ``` + | exceptRoutes: ({ request }) => request.url().includes('/api') + | ``` + | + */ + exceptRoutes: ctx => { + // ignore all routes starting with /v1/ (api) + return ( + ctx.request.url().includes('/v1/') || + ctx.request.url().includes('/import') + ); + }, + + /* + |-------------------------------------------------------------------------- + | Enable Sharing Token Via Cookie + |-------------------------------------------------------------------------- + | + | When the following flag is enabled, AdonisJS will drop `XSRF-TOKEN` + | cookie that frontend frameworks can read and return back as a + | `X-XSRF-TOKEN` header. + | + | The cookie has `httpOnly` flag set to false, so it is little insecure and + | can be turned off when you are not using a frontend framework making + | AJAX requests. + | + */ + enableXsrfCookie: true, + + /* + |-------------------------------------------------------------------------- + | Methods to Validate + |-------------------------------------------------------------------------- + | + | Define an array of HTTP methods to be validated for a valid CSRF token. + | + */ + methods: ['POST', 'PUT', 'PATCH', 'DELETE'], +}; + +/* +|-------------------------------------------------------------------------- +| DNS Prefetching +|-------------------------------------------------------------------------- +| +| DNS prefetching allows browsers to proactively perform domain name +| resolution in background. +| +| Learn more at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control +| +*/ +export const dnsPrefetch: ShieldConfig['dnsPrefetch'] = { + /* + |-------------------------------------------------------------------------- + | Enable/disable this feature + |-------------------------------------------------------------------------- + */ + enabled: true, + + /* + |-------------------------------------------------------------------------- + | Allow or Dis-Allow Explicitly + |-------------------------------------------------------------------------- + | + | The `enabled` boolean does not set `X-DNS-Prefetch-Control` header. However + | the `allow` boolean controls the value of `X-DNS-Prefetch-Control` header. + | + | - When `allow = true`, then `X-DNS-Prefetch-Control = 'on'` + | - When `allow = false`, then `X-DNS-Prefetch-Control = 'off'` + | + */ + allow: true, +}; + +/* +|-------------------------------------------------------------------------- +| Iframe Options +|-------------------------------------------------------------------------- +| +| xFrame defines whether or not your website can be embedded inside an +| iframe. Choose from one of the following options. +| +| - DENY +| - SAMEORIGIN +| - ALLOW-FROM http://example.com +| +| Learn more at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options +*/ +export const xFrame: ShieldConfig['xFrame'] = { + enabled: true, + action: 'DENY', +}; + +/* +|-------------------------------------------------------------------------- +| Http Strict Transport Security +|-------------------------------------------------------------------------- +| +| A security to ensure that a browser always makes a connection over +| HTTPS. +| +| Learn more at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security +| +*/ +export const hsts: ShieldConfig['hsts'] = { + enabled: true, + /* + |-------------------------------------------------------------------------- + | Max Age + |-------------------------------------------------------------------------- + | + | Control, how long the browser should remember that a site is only to be + | accessed using HTTPS. + | + */ + maxAge: '180 days', + + /* + |-------------------------------------------------------------------------- + | Include Subdomains + |-------------------------------------------------------------------------- + | + | Apply rules on the subdomains as well. + | + */ + includeSubDomains: true, + + /* + |-------------------------------------------------------------------------- + | Preloading + |-------------------------------------------------------------------------- + | + | Google maintains a service to register your domain and it will preload + | the HSTS policy. Learn more https://hstspreload.org/ + | + */ + preload: false, +}; + +/* +|-------------------------------------------------------------------------- +| No Sniff +|-------------------------------------------------------------------------- +| +| Browsers have a habit of sniffing content-type of a response. Which means +| files with .txt extension containing Javascript code will be executed as +| Javascript. You can disable this behavior by setting nosniff to false. +| +| Learn more at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options +| +*/ +export const contentTypeSniffing: ShieldConfig['contentTypeSniffing'] = { + enabled: true, +}; diff --git a/config/static.ts b/config/static.ts new file mode 100644 index 0000000..1f7c88f --- /dev/null +++ b/config/static.ts @@ -0,0 +1,10 @@ +import { AssetsConfig } from '@ioc:Adonis/Core/Static'; + +const staticConfig: AssetsConfig = { + enabled: true, + dotFiles: 'ignore', + etag: true, + lastModified: true, +}; + +export default staticConfig; -- cgit v1.2.3-54-g00ecf