created User-Model and Employee-Model

This commit is contained in:
Sockenklaus
2021-10-16 23:19:50 +02:00
parent 4acf451351
commit 93e2b9c445
20 changed files with 2958 additions and 88 deletions

View File

@@ -3,7 +3,8 @@
"commands": [ "commands": [
"./commands", "./commands",
"@adonisjs/core/build/commands/index.js", "@adonisjs/core/build/commands/index.js",
"@adonisjs/repl/build/commands" "@adonisjs/repl/build/commands",
"@adonisjs/lucid/build/commands"
], ],
"exceptionHandlerNamespace": "App/Exceptions/Handler", "exceptionHandlerNamespace": "App/Exceptions/Handler",
"aliases": { "aliases": {
@@ -12,7 +13,18 @@
"Database": "database", "Database": "database",
"Contracts": "contracts" "Contracts": "contracts"
}, },
"preloads": ["./start/routes", "./start/kernel"], "preloads": [
"providers": ["./providers/AppProvider", "@adonisjs/core"], "./start/routes",
"aceProviders": ["@adonisjs/repl"] "./start/kernel"
],
"providers": [
"./providers/AppProvider",
"@adonisjs/core",
"@adonisjs/lucid",
"@adonisjs/session",
"@adonisjs/auth"
],
"aceProviders": [
"@adonisjs/repl"
]
} }

1
.env.example Normal file
View File

@@ -0,0 +1 @@
SESSION_DRIVER=cookie

View File

@@ -48,6 +48,219 @@
"args": [], "args": [],
"aliases": [], "aliases": [],
"flags": [] "flags": []
},
"db:seed": {
"settings": {
"loadApp": true
},
"commandPath": "@adonisjs/lucid/build/commands/DbSeed",
"commandName": "db:seed",
"description": "Execute database seeder files",
"args": [],
"aliases": [],
"flags": [
{
"name": "connection",
"propertyName": "connection",
"type": "string",
"description": "Define a custom database connection for the seeders",
"alias": "c"
},
{
"name": "interactive",
"propertyName": "interactive",
"type": "boolean",
"description": "Run seeders in interactive mode",
"alias": "i"
},
{
"name": "files",
"propertyName": "files",
"type": "array",
"description": "Define a custom set of seeders files names to run",
"alias": "f"
}
]
},
"make:model": {
"settings": {},
"commandPath": "@adonisjs/lucid/build/commands/MakeModel",
"commandName": "make:model",
"description": "Make a new Lucid model",
"args": [
{
"type": "string",
"propertyName": "name",
"name": "name",
"required": true,
"description": "Name of the model class"
}
],
"aliases": [],
"flags": [
{
"name": "migration",
"propertyName": "migration",
"type": "boolean",
"alias": "m",
"description": "Generate the migration for the model"
},
{
"name": "controller",
"propertyName": "controller",
"type": "boolean",
"alias": "c",
"description": "Generate the controller for the model"
}
]
},
"make:migration": {
"settings": {
"loadApp": true
},
"commandPath": "@adonisjs/lucid/build/commands/MakeMigration",
"commandName": "make:migration",
"description": "Make a new migration file",
"args": [
{
"type": "string",
"propertyName": "name",
"name": "name",
"required": true,
"description": "Name of the migration file"
}
],
"aliases": [],
"flags": [
{
"name": "connection",
"propertyName": "connection",
"type": "string",
"description": "The connection flag is used to lookup the directory for the migration file"
},
{
"name": "folder",
"propertyName": "folder",
"type": "string",
"description": "Pre-select a migration directory"
},
{
"name": "create",
"propertyName": "create",
"type": "string",
"description": "Define the table name for creating a new table"
},
{
"name": "table",
"propertyName": "table",
"type": "string",
"description": "Define the table name for altering an existing table"
}
]
},
"make:seeder": {
"settings": {},
"commandPath": "@adonisjs/lucid/build/commands/MakeSeeder",
"commandName": "make:seeder",
"description": "Make a new Seeder file",
"args": [
{
"type": "string",
"propertyName": "name",
"name": "name",
"required": true,
"description": "Name of the seeder class"
}
],
"aliases": [],
"flags": []
},
"migration:run": {
"settings": {
"loadApp": true
},
"commandPath": "@adonisjs/lucid/build/commands/Migration/Run",
"commandName": "migration:run",
"description": "Run pending migrations",
"args": [],
"aliases": [],
"flags": [
{
"name": "connection",
"propertyName": "connection",
"type": "string",
"description": "Define a custom database connection",
"alias": "c"
},
{
"name": "force",
"propertyName": "force",
"type": "boolean",
"description": "Explicitly force to run migrations in production"
},
{
"name": "dry-run",
"propertyName": "dryRun",
"type": "boolean",
"description": "Print SQL queries, instead of running the migrations"
}
]
},
"migration:rollback": {
"settings": {
"loadApp": true
},
"commandPath": "@adonisjs/lucid/build/commands/Migration/Rollback",
"commandName": "migration:rollback",
"description": "Rollback migrations to a given batch number",
"args": [],
"aliases": [],
"flags": [
{
"name": "connection",
"propertyName": "connection",
"type": "string",
"description": "Define a custom database connection",
"alias": "c"
},
{
"name": "force",
"propertyName": "force",
"type": "boolean",
"description": "Explictly force to run migrations in production"
},
{
"name": "dry-run",
"propertyName": "dryRun",
"type": "boolean",
"description": "Print SQL queries, instead of running the migrations"
},
{
"name": "batch",
"propertyName": "batch",
"type": "number",
"description": "Define custom batch number for rollback. Use 0 to rollback to initial state"
}
]
},
"migration:status": {
"settings": {
"loadApp": true
},
"commandPath": "@adonisjs/lucid/build/commands/Migration/Status",
"commandName": "migration:status",
"description": "Check migrations current status.",
"args": [],
"aliases": [],
"flags": [
{
"name": "connection",
"propertyName": "connection",
"type": "string",
"description": "Define a custom database connection",
"alias": "c"
}
]
} }
}, },
"aliases": {} "aliases": {}

View File

@@ -0,0 +1,25 @@
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
export default class EmployeesController {
public async index ({}: HttpContextContract) {
}
public async create ({}: HttpContextContract) {
}
public async store ({}: HttpContextContract) {
}
public async show ({}: HttpContextContract) {
}
public async edit ({}: HttpContextContract) {
}
public async update ({}: HttpContextContract) {
}
public async destroy ({}: HttpContextContract) {
}
}

76
app/Middleware/Auth.ts Normal file
View File

@@ -0,0 +1,76 @@
import { GuardsList } from '@ioc:Adonis/Addons/Auth'
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'
import { AuthenticationException } from '@adonisjs/auth/build/standalone'
/**
* 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()
}
}

View File

@@ -0,0 +1,21 @@
import { 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()
}
}

41
app/Models/Employee.ts Normal file
View File

@@ -0,0 +1,41 @@
import { DateTime } from 'luxon'
import { BaseModel, belongsTo, BelongsTo, column } from '@ioc:Adonis/Lucid/Orm'
import User from 'App/Models/User'
export default class Employee extends BaseModel {
@column({ isPrimary: true })
public id: number
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
@column()
public firstName : string
@column()
public lastName : string
@column()
public shorthand: string
@column()
public email : string
@column()
public phone : string
@column()
public mobile : string
@column()
public contractHours : number
@column()
public userId : number
@belongsTo(() => User)
public user: BelongsTo<typeof User>
}

35
app/Models/User.ts Normal file
View File

@@ -0,0 +1,35 @@
import { DateTime } from 'luxon'
import { BaseModel, beforeSave, column, hasOne, HasOne } from '@ioc:Adonis/Lucid/Orm'
import Hash from '@ioc:Adonis/Core/Hash'
import Employee from 'App/Models/Employee'
export default class User extends BaseModel {
@column({ isPrimary: true })
public id: number
@column.dateTime({ autoCreate: true })
public createdAt: DateTime
@column.dateTime({ autoCreate: true, autoUpdate: true })
public updatedAt: DateTime
@column()
public username: string
@column()
public email: string
@column({serializeAs: null})
public password : string
@hasOne(() => Employee)
public employeeProfile : HasOne<typeof Employee>
@beforeSave()
public static async hashPassword(user: User) {
if(user.$dirty.password){
user.password = await Hash.make(user.password)
}
}
}

86
config/auth.ts Normal file
View File

@@ -0,0 +1,86 @@
/**
* 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'
/*
|--------------------------------------------------------------------------
| 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: ['username'],
/*
|--------------------------------------------------------------------------
| 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'),
},
},
},
}
export default authConfig

53
config/database.ts Normal file
View File

@@ -0,0 +1,53 @@
/**
* Config source: https://git.io/JesV9
*
* 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 { 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'),
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: Application.tmpPath('db.sqlite3'),
},
migrations: {
naturalSort: true,
},
useNullAsDefault: true,
healthCheck: false,
debug: false,
},
}
}
export default databaseConfig

118
config/session.ts Normal file
View File

@@ -0,0 +1,118 @@
/**
* 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 '@ioc:Adonis/Addons/Session'
const sessionConfig: 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 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: false,
/*
|--------------------------------------------------------------------------
| 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',
}
export default sessionConfig

72
contracts/auth.ts Normal file
View File

@@ -0,0 +1,72 @@
/**
* Contract source: https://git.io/JOdz5
*
* Feel free to let us know via PR, if you find something broken in this
* file.
*/
import User from 'App/Models/User'
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 {
/*
|--------------------------------------------------------------------------
| 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 User>
config: LucidProviderConfig<typeof User>
}
}
/*
|--------------------------------------------------------------------------
| 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 {
/*
|--------------------------------------------------------------------------
| 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'>
}
}
}

View File

@@ -0,0 +1 @@
// import Factory from '@ioc:Adonis/Lucid/Factory'

View File

@@ -0,0 +1,32 @@
import BaseSchema from '@ioc:Adonis/Lucid/Schema'
export default class Employees extends BaseSchema {
protected tableName = 'employees'
public async up () {
this.schema.createTable(this.tableName, (table) => {
table.increments('id')
/**
* Uses timestamptz for PostgreSQL and DATETIME2 for MSSQL
*/
table.timestamp('created_at', { useTz: true })
table.timestamp('updated_at', { useTz: true })
table.string('first_name ')
table.string('last_name')
table.string('shorthand').unique()
table.string('email')
table.string('phone')
table.string('mobile')
table.decimal('contract_hours', 2, 2)
table
.integer('user_id')
.unsigned()
.references('users.id')
})
}
public async down () {
this.schema.dropTable(this.tableName)
}
}

View File

@@ -0,0 +1,25 @@
import BaseSchema from '@ioc:Adonis/Lucid/Schema'
export default class Users extends BaseSchema {
protected tableName = 'users'
public async up () {
this.schema.createTable(this.tableName, (table) => {
table.increments('id')
/**
* Uses timestamptz for PostgreSQL and DATETIME2 for MSSQL
*/
table.timestamp('created_at', { useTz: true })
table.timestamp('updated_at', { useTz: true })
table.string('username').notNullable().unique()
table.string('email').notNullable().unique()
table.string('password').notNullable()
})
}
public async down () {
this.schema.dropTable(this.tableName)
}
}

2179
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -23,10 +23,15 @@
"youch-terminal": "^1.1.1" "youch-terminal": "^1.1.1"
}, },
"dependencies": { "dependencies": {
"@adonisjs/auth": "^8.0.10",
"@adonisjs/core": "^5.4.0", "@adonisjs/core": "^5.4.0",
"@adonisjs/lucid": "^16.2.1",
"@adonisjs/repl": "^3.1.6", "@adonisjs/repl": "^3.1.6",
"@adonisjs/session": "^6.1.2",
"luxon": "^2.0.2",
"proxy-addr": "^2.0.7", "proxy-addr": "^2.0.7",
"reflect-metadata": "^0.1.13", "reflect-metadata": "^0.1.13",
"source-map-support": "^0.5.20" "source-map-support": "^0.5.20",
"sqlite3": "^5.0.2"
} }
} }

View File

@@ -38,4 +38,6 @@ Server.middleware.register([() => import('@ioc:Adonis/Core/BodyParser')])
| Route.get('dashboard', 'UserController.dashboard').middleware('auth') | Route.get('dashboard', 'UserController.dashboard').middleware('auth')
| |
*/ */
Server.middleware.registerNamed({}) Server.middleware.registerNamed({
auth: () => import('App/Middleware/Auth')
})

View File

@@ -20,6 +20,4 @@
import Route from '@ioc:Adonis/Core/Route' import Route from '@ioc:Adonis/Core/Route'
Route.get('/', async () => { Route.resource('employees', 'EmployeesController').except(['create', 'edit'])
return { hello: 'world' }
})

View File

@@ -1,17 +1,36 @@
{ {
"extends": "./node_modules/adonis-preset-ts/tsconfig", "extends": "./node_modules/adonis-preset-ts/tsconfig",
"include": ["**/*"], "include": [
"exclude": ["node_modules", "build"], "**/*"
],
"exclude": [
"node_modules",
"build"
],
"compilerOptions": { "compilerOptions": {
"outDir": "build", "outDir": "build",
"rootDir": "./", "rootDir": "./",
"sourceMap": true, "sourceMap": true,
"paths": { "paths": {
"App/*": ["./app/*"], "App/*": [
"Config/*": ["./config/*"], "./app/*"
"Contracts/*": ["./contracts/*"], ],
"Database/*": ["./database/*"] "Config/*": [
"./config/*"
],
"Contracts/*": [
"./contracts/*"
],
"Database/*": [
"./database/*"
]
}, },
"types": ["@adonisjs/core", "@adonisjs/repl"] "types": [
"@adonisjs/core",
"@adonisjs/repl",
"@adonisjs/lucid",
"@adonisjs/session",
"@adonisjs/auth"
]
} }
} }