This commit is contained in:
Tutur33
2023-11-24 22:35:41 +01:00
parent 3c0b507a93
commit 7644b2a0f7
45165 changed files with 4803356 additions and 3 deletions
+34
View File
@@ -0,0 +1,34 @@
/**
* Config source: https://git.io/JY0mp
*
* Feel free to let us know via PR, if you find something broken in this config
* file.
*/
import type { AuthConfig } from '@ioc:Adonis/Addons/Auth'
/*
|--------------------------------------------------------------------------
| 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: '{{ guards.0 }}',
guards: {
{{#hasGuard.web}}
{{> web_guard}}
{{/hasGuard.web}}
{{#hasGuard.api}}
{{> api_guard}}
{{/hasGuard.api}}
{{#hasGuard.basic}}
{{> basic_guard}}
{{/hasGuard.basic}}
},
}
export default authConfig
@@ -0,0 +1,22 @@
/*
|--------------------------------------------------------------------------
| 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',
{{> token_provider}}
provider: {
{{> provider}}
},
},
@@ -0,0 +1,19 @@
/*
|--------------------------------------------------------------------------
| 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: {
{{> provider}}
},
},
@@ -0,0 +1,19 @@
/*
|--------------------------------------------------------------------------
| 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: 'api_tokens',
foreignKey: 'user_id',
},
@@ -0,0 +1,22 @@
/*
|--------------------------------------------------------------------------
| Redis provider for managing tokens
|--------------------------------------------------------------------------
|
| Uses Redis for managing tokens. We recommend using the "redis" driver
| over the "database" driver when the tokens based auth is the
| primary authentication mode.
|
| Redis ensure that all the expired tokens gets cleaned up automatically.
| Whereas with SQL, you have to cleanup expired tokens manually.
|
| 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: 'redis',
redisConnection: 'local',
foreignKey: 'user_id',
},
@@ -0,0 +1,43 @@
/*
|--------------------------------------------------------------------------
| Driver
|--------------------------------------------------------------------------
|
| Name of the driver
|
*/
driver: 'database',
/*
|--------------------------------------------------------------------------
| Identifier key
|--------------------------------------------------------------------------
|
| The identifier key is the unique key inside the defined database table.
| 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'],
/*
|--------------------------------------------------------------------------
| Database table
|--------------------------------------------------------------------------
|
| The database table to query. Make sure the database table has a `password`
| field and `remember_me_token` column.
|
*/
usersTable: '{{ usersTableName }}',
@@ -0,0 +1,45 @@
/*
|--------------------------------------------------------------------------
| 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('{{{ modelNamespace }}}'),
@@ -0,0 +1,17 @@
/*
|--------------------------------------------------------------------------
| 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: {
{{> provider}}
},
},
+55
View File
@@ -0,0 +1,55 @@
/**
* Contract source: https://git.io/JOdz5
*
* Feel free to let us know via PR, if you find something broken in this
* file.
*/
{{#modelNamespace}}
import {{ modelName }} from '{{{ modelNamespace }}}'
{{/modelNamespace}}
declare module '@ioc:Adonis/Addons/Auth' {
/*
|--------------------------------------------------------------------------
| Providers
|--------------------------------------------------------------------------
|
| The providers are used to fetch users. The Auth module comes pre-bundled
| with two providers that are `Lucid` and `Database`. Both uses database
| to fetch user details.
|
| You can also create and register your own custom providers.
|
*/
interface ProvidersList {
{{> provider}}
}
/*
|--------------------------------------------------------------------------
| Guards
|--------------------------------------------------------------------------
|
| The guards are used for authenticating users using different drivers.
| The auth module comes with 3 different guards.
|
| - SessionGuardContract
| - BasicAuthGuardContract
| - OATGuardContract ( Opaque access token )
|
| Every guard needs a provider for looking up users from the database.
|
*/
interface GuardsList {
{{#hasGuard.web}}
{{> web_guard}}
{{/hasGuard.web}}
{{#hasGuard.api}}
{{> api_guard}}
{{/hasGuard.api}}
{{#hasGuard.basic}}
{{> basic_guard}}
{{/hasGuard.basic}}
}
}
@@ -0,0 +1,14 @@
/*
|--------------------------------------------------------------------------
| OAT Guard
|--------------------------------------------------------------------------
|
| OAT, stands for (Opaque access tokens) guard uses database backed tokens
| to authenticate requests.
|
*/
api: {
implementation: OATGuardContract<'user', 'api'>
config: OATGuardConfig<'user'>
client: OATClientContract<'user'>
}
@@ -0,0 +1,14 @@
/*
|--------------------------------------------------------------------------
| Basic Auth Guard
|--------------------------------------------------------------------------
|
| The basic guard uses basic auth for maintaining user login state. It uses
| the `user` provider for fetching user details.
|
*/
basic: {
implementation: BasicAuthGuardContract<'user', 'basic'>
config: BasicAuthGuardConfig<'user'>
client: BasicAuthClientContract<'user'>
}
@@ -0,0 +1,16 @@
/*
|--------------------------------------------------------------------------
| User Provider
|--------------------------------------------------------------------------
|
| The following provider directlly uses Database query builder for fetching
| user details from the database for authentication.
|
| You can create multiple providers using the same underlying driver with
| different database tables.
|
*/
user: {
implementation: DatabaseProviderContract<DatabaseProviderRow>
config: DatabaseProviderConfig
}
@@ -0,0 +1,16 @@
/*
|--------------------------------------------------------------------------
| User Provider
|--------------------------------------------------------------------------
|
| The following provider uses Lucid models as a driver for fetching user
| details from the database for authentication.
|
| You can create multiple providers using the same underlying driver with
| different Lucid models.
|
*/
user: {
implementation: LucidProviderContract<typeof {{ modelName }}>
config: LucidProviderConfig<typeof {{ modelName }}>
}
@@ -0,0 +1,14 @@
/*
|--------------------------------------------------------------------------
| Web Guard
|--------------------------------------------------------------------------
|
| The web guard uses sessions for maintaining user login state. It uses
| the `user` provider for fetching user details.
|
*/
web: {
implementation: SessionGuardContract<'user', 'web'>
config: SessionGuardConfig<'user'>
client: SessionClientContract<'user'>
}
+76
View File
@@ -0,0 +1,76 @@
import { AuthenticationException } from '@adonisjs/auth/build/standalone'
import type { GuardsList } from '@ioc:Adonis/Addons/Auth'
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
/**
* Auth middleware is meant to restrict un-authenticated access to a given route
* or a group of routes.
*
* You must register this middleware inside `start/kernel.ts` file under the list
* of named middleware.
*/
export default class AuthMiddleware {
/**
* The URL to redirect to when request is Unauthorized
*/
protected redirectTo = '/login'
/**
* Authenticates the current HTTP request against a custom set of defined
* guards.
*
* The authentication loop stops as soon as the user is authenticated using any
* of the mentioned guards and that guard will be used by the rest of the code
* during the current request.
*/
protected async authenticate(auth: HttpContextContract['auth'], guards: (keyof GuardsList)[]) {
/**
* Hold reference to the guard last attempted within the for loop. We pass
* the reference of the guard to the "AuthenticationException", so that
* it can decide the correct response behavior based upon the guard
* driver
*/
let guardLastAttempted: string | undefined
for (let guard of guards) {
guardLastAttempted = guard
if (await auth.use(guard).check()) {
/**
* Instruct auth to use the given guard as the default guard for
* the rest of the request, since the user authenticated
* succeeded here
*/
auth.defaultGuard = guard
return true
}
}
/**
* Unable to authenticate using any guard
*/
throw new AuthenticationException(
'Unauthorized access',
'E_UNAUTHORIZED_ACCESS',
guardLastAttempted,
this.redirectTo,
)
}
/**
* Handle request
*/
public async handle (
{ auth }: HttpContextContract,
next: () => Promise<void>,
customGuards: (keyof GuardsList)[]
) {
/**
* Uses the user defined guards or the default guard mentioned in
* the config file
*/
const guards = customGuards.length ? customGuards : [auth.name]
await this.authenticate(auth, guards)
await next()
}
}
+21
View File
@@ -0,0 +1,21 @@
import type { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
/**
* Silent auth middleware can be used as a global middleware to silent check
* if the user is logged-in or not.
*
* The request continues as usual, even when the user is not logged-in.
*/
export default class SilentAuthMiddleware {
/**
* Handle request
*/
public async handle({ auth }: HttpContextContract, next: () => Promise<void>) {
/**
* Check if user is logged-in or not. If yes, then `ctx.auth.user` will be
* set to the instance of the currently logged in user.
*/
await auth.check()
await next()
}
}
+25
View File
@@ -0,0 +1,25 @@
import BaseSchema from '@ioc:Adonis/Lucid/Schema'
export default class extends BaseSchema {
protected tableName = '{{ tokensTableName }}'
public async up() {
this.schema.createTable(this.tableName, (table) => {
table.increments('id').primary()
table.integer('user_id').unsigned().references('id').inTable('{{ usersTableName }}').onDelete('CASCADE')
table.string('name').notNullable()
table.string('type').notNullable()
table.string('token', 64).notNullable().unique()
/**
* Uses timestampz for PostgreSQL and DATETIME2 for MSSQL
*/
table.timestamp('expires_at', { useTz: true }).nullable()
table.timestamp('created_at', { useTz: true }).notNullable()
})
}
public async down() {
this.schema.dropTable(this.tableName)
}
}
+24
View File
@@ -0,0 +1,24 @@
import BaseSchema from '@ioc:Adonis/Lucid/Schema'
export default class extends BaseSchema {
protected tableName = '{{ usersTableName }}'
public async up() {
this.schema.createTable(this.tableName, (table) => {
table.increments('id').primary()
table.string('email', 255).notNullable().unique()
table.string('password', 180).notNullable()
table.string('remember_me_token').nullable()
/**
* Uses timestampz for PostgreSQL and DATETIME2 for MSSQL
*/
table.timestamp('created_at', { useTz: true }).notNullable()
table.timestamp('updated_at', { useTz: true }).notNullable()
})
}
public async down() {
this.schema.dropTable(this.tableName)
}
}
+30
View File
@@ -0,0 +1,30 @@
import { DateTime } from 'luxon'
import Hash from '@ioc:Adonis/Core/Hash'
import { column, beforeSave, BaseModel } from '@ioc:Adonis/Lucid/Orm'
export default class {{ modelName }} extends BaseModel {
@column({ isPrimary: true })
public id: number
@column()
public email: string
@column({ serializeAs: null })
public password: string
@column()
public rememberMeToken: string | null
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
@beforeSave()
public static async hashPassword ({{ modelReference }}: {{ modelName }}) {
if ({{ modelReference }}.$dirty.password) {
{{ modelReference }}.password = await Hash.make({{ modelReference }}.password)
}
}
}