feat: updating user email controller

This commit is contained in:
Sergey Yarkov 2021-09-05 20:26:13 +03:00
parent d2edc9eb6f
commit a88e37500f
14 changed files with 704 additions and 20 deletions

View File

@ -4,7 +4,8 @@
"./commands", "./commands",
"@adonisjs/core/commands", "@adonisjs/core/commands",
"@adonisjs/repl/build/commands", "@adonisjs/repl/build/commands",
"@adonisjs/lucid/build/commands" "@adonisjs/lucid/build/commands",
"@adonisjs/mail/build/commands"
], ],
"exceptionHandlerNamespace": "App/Exceptions/Handler", "exceptionHandlerNamespace": "App/Exceptions/Handler",
"namespaces": { "namespaces": {
@ -22,14 +23,27 @@
"Database": "database", "Database": "database",
"Contracts": "contracts" "Contracts": "contracts"
}, },
"preloads": ["./routes/index", "./start/kernel"], "preloads": [
"./routes/index",
"./start/kernel"
],
"providers": [ "providers": [
"./providers/AppProvider", "./providers/AppProvider",
"./providers/CloudinaryProvider", "./providers/CloudinaryProvider",
"@adonisjs/core", "@adonisjs/core",
"@adonisjs/lucid", "@adonisjs/lucid",
"@adonisjs/auth", "@adonisjs/auth",
"@adonisjs/redis" "@adonisjs/redis",
"@adonisjs/mail",
"@adonisjs/view"
], ],
"aceProviders": ["@adonisjs/repl"] "aceProviders": [
"@adonisjs/repl"
],
"metaFiles": [
{
"pattern": "resources/views/**/*.edge",
"reloadServer": false
}
]
} }

View File

@ -16,3 +16,10 @@ CLOUDINARY_CLOUD_NAME=
CLOUDINARY_API_KEY= CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET= CLOUDINARY_API_SECRET=
CLOUDINARY_SECURE=true CLOUDINARY_SECURE=true
SMTP_HOST=localhost
SMTP_PORT=587
SMTP_USERNAME=<username>
SMTP_PASSWORD=<password>
MAILGUN_API_KEY=<mailgun-api-key>
MAILGUN_DOMAIN=<your-domain>
CACHE_VIEWS=false

View File

@ -2,7 +2,7 @@
"commands": { "commands": {
"dump:rcfile": { "dump:rcfile": {
"settings": {}, "settings": {},
"commandPath": "@adonisjs/core/commands/DumpRc", "commandPath": "@adonisjs/core/build/commands/DumpRc",
"commandName": "dump:rcfile", "commandName": "dump:rcfile",
"description": "Dump contents of .adonisrc.json file along with defaults", "description": "Dump contents of .adonisrc.json file along with defaults",
"args": [], "args": [],
@ -13,7 +13,7 @@
"settings": { "settings": {
"loadApp": true "loadApp": true
}, },
"commandPath": "@adonisjs/core/commands/ListRoutes", "commandPath": "@adonisjs/core/build/commands/ListRoutes",
"commandName": "list:routes", "commandName": "list:routes",
"description": "List application routes", "description": "List application routes",
"args": [], "args": [],
@ -29,7 +29,7 @@
}, },
"generate:key": { "generate:key": {
"settings": {}, "settings": {},
"commandPath": "@adonisjs/core/commands/GenerateKey", "commandPath": "@adonisjs/core/build/commands/GenerateKey",
"commandName": "generate:key", "commandName": "generate:key",
"description": "Generate a new APP_KEY secret", "description": "Generate a new APP_KEY secret",
"args": [], "args": [],
@ -261,6 +261,23 @@
"alias": "c" "alias": "c"
} }
] ]
},
"make:mailer": {
"settings": {},
"commandPath": "@adonisjs/mail/build/commands/MakeMailer",
"commandName": "make:mailer",
"description": "Make a new mailer class",
"args": [
{
"type": "string",
"propertyName": "name",
"name": "name",
"required": true,
"description": "Name of the mailer class"
}
],
"aliases": [],
"flags": []
} }
}, },
"aliases": {} "aliases": {}

View File

@ -1,5 +1,6 @@
import { Exception, inject, Ioc } from '@adonisjs/core/build/standalone'; import { Exception, inject, Ioc } from '@adonisjs/core/build/standalone';
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext'; import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
import { schema, rules } from '@ioc:Adonis/Core/Validator';
/** /**
* Services * Services
@ -52,6 +53,46 @@ export default class MeController extends BaseController {
return this.sendResponse(ctx, result.data, result.message, result.status); return this.sendResponse(ctx, result.data, result.message, result.status);
} }
/**
* Send confirmation code to new email
* PATCH /me/email
*/
// eslint-disable-next-line class-methods-use-this
public async changeEmail(ctx: HttpContextContract) {
const payload = await ctx.request.validate({
schema: schema.create({
email: schema.string({}, [rules.email()]),
}),
});
const result = await MeService.changeUserEmail(payload.email);
if (!result.success && result.error) {
throw new Exception(result.message, result.status, result.error.code);
}
return this.sendResponse(ctx, result.data, result.message, result.status);
}
/**
* Confirm code and update user email
* POST /me/email/change/confirm
*/
// eslint-disable-next-line class-methods-use-this
public async changeEmailConfirm(ctx: HttpContextContract) {
const confirmChangeEmailSchema = schema.create({
email: schema.string({}, [rules.email()]),
confirmationCode: schema.number(),
});
const payload = await ctx.request.validate({ schema: confirmChangeEmailSchema });
const result = await MeService.changeUserEmailConfirm(ctx, payload.email, payload.confirmationCode);
if (!result.success && result.error) {
throw new Exception(result.message, result.status, result.error.code);
}
return this.sendResponse(ctx, result.data, result.message, result.status);
}
/** /**
* Update contacts of authenticated user * Update contacts of authenticated user
* PUT /me/contacts * PUT /me/contacts

View File

@ -7,6 +7,7 @@ enum StatusCodeEnum {
FORBIDDEN = 403, FORBIDDEN = 403,
NOT_FOUND = 404, NOT_FOUND = 404,
INTERNAL_SERVER = 500, INTERNAL_SERVER = 500,
SERVICE_UNAVAILABLE = 503,
} }
export default StatusCodeEnum; export default StatusCodeEnum;

View File

@ -1,5 +1,8 @@
import { inject, Ioc } from '@adonisjs/core/build/standalone'; import { inject, Ioc } from '@adonisjs/core/build/standalone';
import { AuthContract } from '@ioc:Adonis/Addons/Auth'; import { AuthContract } from '@ioc:Adonis/Addons/Auth';
import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext';
import Redis from '@ioc:Adonis/Addons/Redis';
import Mail from '@ioc:Adonis/Addons/Mail';
import Hash from '@ioc:Adonis/Core/Hash'; import Hash from '@ioc:Adonis/Core/Hash';
import Logger from '@ioc:Adonis/Core/Logger'; import Logger from '@ioc:Adonis/Core/Logger';
import StatusCodeEnum from 'App/Datatypes/Enums/StatusCodeEnum'; import StatusCodeEnum from 'App/Datatypes/Enums/StatusCodeEnum';
@ -95,6 +98,98 @@ export default class MeService {
}; };
} }
public static async changeUserEmail(email: string): Promise<IResponse> {
const isConfirmationCodeExist = await Redis.get(`code.change.email:${email}`);
/**
* Confirmation code has not expired
*/
if (isConfirmationCodeExist) {
return {
success: false,
status: StatusCodeEnum.SERVICE_UNAVAILABLE,
message: 'Please wait a few seconds before send new confirmation code.',
data: {},
error: {
code: 'E_SERVICE_UNAVAILABLE',
},
};
}
/**
* Create new confirmation code and send to email
*/
const EXPIRE_SECONDS = 60;
const confirmationCode = Math.floor(1000 + Math.random() * 9000).toString();
await Mail.send(message => {
message
.from('learn-management-system@sandbox7727dde9c8aa4686a308dbb9c0045acb.mailgun.org')
.to(email)
.subject('Confirmation code.')
.htmlView('emails/change_email_confirm', { confirmationCode });
});
await Redis.set(`code.change.email:${email}`, confirmationCode, 'EX', EXPIRE_SECONDS);
return {
success: true,
status: StatusCodeEnum.OK,
message: 'The confirmation code has been sent.',
data: {
expired_seconds: EXPIRE_SECONDS,
},
};
}
public static async changeUserEmailConfirm(
ctx: HttpContextContract,
email: string,
code: number
): Promise<IResponse> {
const user = await ctx.auth.use('api').authenticate();
const confirmationCode = await Redis.get(`code.change.email:${email}`);
/**
* Confirmation code not found
*/
if (confirmationCode === null) {
return {
success: false,
status: StatusCodeEnum.NOT_FOUND,
message: 'Cannot find the confirmation code for this email.',
data: {},
error: {
code: 'E_NOT_FOUND',
},
};
}
if (Number.parseInt(confirmationCode, 10) !== code) {
return {
success: false,
status: StatusCodeEnum.BAD_REQUEST,
message: 'Confirmation code is invalid.',
data: {},
error: {
code: 'E_BAD_REQUEST',
},
};
}
/**
* Update user email and delete confirmation code
*/
await user.merge({ email }).save();
await Redis.del(`code.change.email:${email}`);
return {
success: true,
status: StatusCodeEnum.OK,
message: 'User email updated.',
data: { email },
};
}
/** /**
* Update user conctact * Update user conctact
* *

76
config/mail.ts Normal file
View File

@ -0,0 +1,76 @@
/**
* 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 '@ioc:Adonis/Addons/Mail';
const mailConfig: MailConfig = {
/*
|--------------------------------------------------------------------------
| Default mailer
|--------------------------------------------------------------------------
|
| The following mailer will be used to send emails, when you don't specify
| a mailer
|
*/
mailer: 'mailgun',
/*
|--------------------------------------------------------------------------
| 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',
host: Env.get('SMTP_HOST'),
port: Env.get('SMTP_PORT'),
auth: {
user: Env.get('SMTP_USERNAME'),
pass: Env.get('SMTP_PASSWORD'),
type: 'login',
},
},
/*
|--------------------------------------------------------------------------
| 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'),
},
},
};
export default mailConfig;

15
contracts/mail.ts Normal file
View File

@ -0,0 +1,15 @@
/**
* Contract source: https://git.io/JvgAT
*
* Feel free to let us know via PR, if you find something broken in this contract
* file.
*/
declare module '@ioc:Adonis/Addons/Mail' {
import { MailDrivers } from '@ioc:Adonis/Addons/Mail';
interface MailersList {
smtp: MailDrivers['smtp'];
mailgun: MailDrivers['mailgun'];
}
}

6
env.ts
View File

@ -30,6 +30,12 @@ export default Env.rules({
REDIS_HOST: Env.schema.string({ format: 'host' }), REDIS_HOST: Env.schema.string({ format: 'host' }),
REDIS_PORT: Env.schema.number(), REDIS_PORT: Env.schema.number(),
REDIS_PASSWORD: Env.schema.string.optional(), REDIS_PASSWORD: Env.schema.string.optional(),
SMTP_HOST: Env.schema.string({ format: 'host' }),
SMTP_PORT: Env.schema.number(),
SMTP_USERNAME: Env.schema.string(),
SMTP_PASSWORD: Env.schema.string(),
MAILGUN_API_KEY: Env.schema.string(),
MAILGUN_DOMAIN: Env.schema.string(),
CLOUDINARY_CLOUD_NAME: Env.schema.string(), CLOUDINARY_CLOUD_NAME: Env.schema.string(),
CLOUDINARY_API_KEY: Env.schema.string(), CLOUDINARY_API_KEY: Env.schema.string(),
CLOUDINARY_API_SECRET: Env.schema.string(), CLOUDINARY_API_SECRET: Env.schema.string(),

391
package-lock.json generated
View File

@ -674,6 +674,52 @@
"slash": "^3.0.0" "slash": "^3.0.0"
} }
}, },
"@adonisjs/mail": {
"version": "7.2.4",
"resolved": "https://registry.npmjs.org/@adonisjs/mail/-/mail-7.2.4.tgz",
"integrity": "sha512-ddoeT5rGV1JgLjMmOIFxzFkWFDc1gb59d+CQ45DNOyDboSEkSvKt5O2LBnBuTKMBjFUMUjvnYDjkb7QgbFN2fw==",
"requires": {
"@poppinss/colors": "^2.1.5",
"@poppinss/manager": "^4.0.4",
"@poppinss/utils": "^3.2.0",
"fastq": "^1.12.0",
"get-stream": "^6.0.1",
"got": "^11.8.2",
"ical-generator": "^3.0.0",
"multi-part": "^3.0.0",
"nodemailer": "^6.6.3"
},
"dependencies": {
"@poppinss/utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@poppinss/utils/-/utils-3.2.0.tgz",
"integrity": "sha512-gnqlrxE4zMvqW+LpviyCWCg4+RShCYCFyBdVTyg9ZZEEgPBV9bEY+YB5r/2klFrKx30k9nfClHVI2n8ZKmXgsw==",
"requires": {
"@types/bytes": "^3.1.1",
"@types/he": "^1.1.2",
"buffer-alloc": "^1.2.0",
"bytes": "^3.1.0",
"change-case": "^4.1.2",
"cuid": "^2.1.8",
"fs-readdir-recursive": "^1.1.0",
"he": "^1.2.0",
"kind-of": "^6.0.3",
"lodash": "^4.17.21",
"ms": "^2.1.3",
"pluralize": "^8.0.0",
"require-all": "^3.0.0",
"resolve-from": "^5.0.0",
"slugify": "^1.6.0",
"truncatise": "0.0.8"
}
},
"slugify": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.0.tgz",
"integrity": "sha512-FkMq+MQc5hzYgM86nLuHI98Acwi3p4wX+a5BO9Hhw4JdK4L7WueIiZ4tXEobImPqBz2sVcV0+Mu3GRB30IGang=="
}
}
},
"@adonisjs/profiler": { "@adonisjs/profiler": {
"version": "6.0.6", "version": "6.0.6",
"resolved": "https://registry.npmjs.org/@adonisjs/profiler/-/profiler-6.0.6.tgz", "resolved": "https://registry.npmjs.org/@adonisjs/profiler/-/profiler-6.0.6.tgz",
@ -911,6 +957,16 @@
} }
} }
}, },
"@adonisjs/view": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/@adonisjs/view/-/view-6.1.0.tgz",
"integrity": "sha512-6odN0FLSM4+0zVOQ14BTXBymDsCRrI95yGbAOUex6hMeSvBBff6f+VlH+WsiPS7xyKewI7ihZx6yRsVERBb0bw==",
"requires": {
"edge-error": "^2.0.5",
"edge-supercharged": "^3.1.1",
"edge.js": "^5.3.1"
}
},
"@arr/every": { "@arr/every": {
"version": "1.0.1", "version": "1.0.1",
"resolved": "https://registry.npmjs.org/@arr/every/-/every-1.0.1.tgz", "resolved": "https://registry.npmjs.org/@arr/every/-/every-1.0.1.tgz",
@ -1173,6 +1229,11 @@
"resolved": "https://registry.npmjs.org/@poppinss/hooks/-/hooks-3.0.4.tgz", "resolved": "https://registry.npmjs.org/@poppinss/hooks/-/hooks-3.0.4.tgz",
"integrity": "sha512-vVtd8v3grQ0JcbZgvUrUIUeMqTcHkE31nJGE/jRxDEbCiusBwBJD6D16a5Wzbl+o6xRldlhIcdDn+AE8PUpuVA==" "integrity": "sha512-vVtd8v3grQ0JcbZgvUrUIUeMqTcHkE31nJGE/jRxDEbCiusBwBJD6D16a5Wzbl+o6xRldlhIcdDn+AE8PUpuVA=="
}, },
"@poppinss/inspect": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@poppinss/inspect/-/inspect-1.0.1.tgz",
"integrity": "sha512-kLeEaBSGhlleyYvKc7c9s3uE6xv7cwyulE0EgHf4jU/CL96h0yC4mkdw1wvC1l1PYYQozCGy46FwMBAAMOobCA=="
},
"@poppinss/manager": { "@poppinss/manager": {
"version": "4.0.4", "version": "4.0.4",
"resolved": "https://registry.npmjs.org/@poppinss/manager/-/manager-4.0.4.tgz", "resolved": "https://registry.npmjs.org/@poppinss/manager/-/manager-4.0.4.tgz",
@ -1248,6 +1309,19 @@
"truncatise": "0.0.8" "truncatise": "0.0.8"
} }
}, },
"@sindresorhus/is": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz",
"integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g=="
},
"@szmarczak/http-timer": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
"integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
"requires": {
"defer-to-connect": "^2.0.0"
}
},
"@tokenizer/token": { "@tokenizer/token": {
"version": "0.3.0", "version": "0.3.0",
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
@ -1258,6 +1332,17 @@
"resolved": "https://registry.npmjs.org/@types/bytes/-/bytes-3.1.1.tgz", "resolved": "https://registry.npmjs.org/@types/bytes/-/bytes-3.1.1.tgz",
"integrity": "sha512-lOGyCnw+2JVPKU3wIV0srU0NyALwTBJlVSx5DfMQOFuuohA8y9S8orImpuIQikZ0uIQ8gehrRjxgQC1rLRi11w==" "integrity": "sha512-lOGyCnw+2JVPKU3wIV0srU0NyALwTBJlVSx5DfMQOFuuohA8y9S8orImpuIQikZ0uIQ8gehrRjxgQC1rLRi11w=="
}, },
"@types/cacheable-request": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz",
"integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==",
"requires": {
"@types/http-cache-semantics": "*",
"@types/keyv": "*",
"@types/node": "*",
"@types/responselike": "*"
}
},
"@types/faker": { "@types/faker": {
"version": "5.5.7", "version": "5.5.7",
"resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.5.7.tgz", "resolved": "https://registry.npmjs.org/@types/faker/-/faker-5.5.7.tgz",
@ -1286,6 +1371,11 @@
"resolved": "https://registry.npmjs.org/@types/he/-/he-1.1.2.tgz", "resolved": "https://registry.npmjs.org/@types/he/-/he-1.1.2.tgz",
"integrity": "sha512-kSJPcLO1x+oolc0R89pUl2kozldQ/fVQ1C1p5mp8fPoLdF/ZcBvckaTC2M8xXh3GYendXvCpy5m/a2eSbfgNgw==" "integrity": "sha512-kSJPcLO1x+oolc0R89pUl2kozldQ/fVQ1C1p5mp8fPoLdF/ZcBvckaTC2M8xXh3GYendXvCpy5m/a2eSbfgNgw=="
}, },
"@types/http-cache-semantics": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
"integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ=="
},
"@types/ioredis": { "@types/ioredis": {
"version": "4.27.1", "version": "4.27.1",
"resolved": "https://registry.npmjs.org/@types/ioredis/-/ioredis-4.27.1.tgz", "resolved": "https://registry.npmjs.org/@types/ioredis/-/ioredis-4.27.1.tgz",
@ -1306,6 +1396,14 @@
"integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=",
"dev": true "dev": true
}, },
"@types/keyv": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz",
"integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==",
"requires": {
"@types/node": "*"
}
},
"@types/luxon": { "@types/luxon": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.0.2.tgz", "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.0.2.tgz",
@ -1349,6 +1447,14 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/responselike": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz",
"integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==",
"requires": {
"@types/node": "*"
}
},
"@types/stack-trace": { "@types/stack-trace": {
"version": "0.0.29", "version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/stack-trace/-/stack-trace-0.0.29.tgz", "resolved": "https://registry.npmjs.org/@types/stack-trace/-/stack-trace-0.0.29.tgz",
@ -1858,6 +1964,11 @@
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
"integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ=="
}, },
"astring": {
"version": "1.7.5",
"resolved": "https://registry.npmjs.org/astring/-/astring-1.7.5.tgz",
"integrity": "sha512-lobf6RWXb8c4uZ7Mdq0U12efYmpD1UFnyOWVJPTa3ukqZrMopav+2hdNu0hgBF0JIBFK9QgrBDfwYvh3DFJDAA=="
},
"atob": { "atob": {
"version": "2.1.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
@ -2078,6 +2189,35 @@
"unset-value": "^1.0.0" "unset-value": "^1.0.0"
} }
}, },
"cacheable-lookup": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
"integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA=="
},
"cacheable-request": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz",
"integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==",
"requires": {
"clone-response": "^1.0.2",
"get-stream": "^5.1.0",
"http-cache-semantics": "^4.0.0",
"keyv": "^4.0.0",
"lowercase-keys": "^2.0.0",
"normalize-url": "^6.0.1",
"responselike": "^2.0.0"
},
"dependencies": {
"get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"requires": {
"pump": "^3.0.0"
}
}
}
},
"call-bind": { "call-bind": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
@ -2264,6 +2404,14 @@
"string-width": "^4.2.0" "string-width": "^4.2.0"
} }
}, },
"clone-response": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
"integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
"requires": {
"mimic-response": "^1.0.0"
}
},
"cloudinary": { "cloudinary": {
"version": "1.26.3", "version": "1.26.3",
"resolved": "https://registry.npmjs.org/cloudinary/-/cloudinary-1.26.3.tgz", "resolved": "https://registry.npmjs.org/cloudinary/-/cloudinary-1.26.3.tgz",
@ -2512,6 +2660,21 @@
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
"dev": true "dev": true
}, },
"decompress-response": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"requires": {
"mimic-response": "^3.1.0"
},
"dependencies": {
"mimic-response": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="
}
}
},
"deep-extend": { "deep-extend": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@ -2524,6 +2687,11 @@
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true "dev": true
}, },
"defer-to-connect": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
"integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg=="
},
"define-lazy-prop": { "define-lazy-prop": {
"version": "2.0.0", "version": "2.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
@ -2643,6 +2811,90 @@
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz",
"integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q==" "integrity": "sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q=="
}, },
"edge-error": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/edge-error/-/edge-error-2.0.6.tgz",
"integrity": "sha512-hXJDgkAVPypbPrwc0JSb+SOgchk9fKp7ZRF43ikM1L/XqhKcxX5oh1ilLQeC/UtBBLm85Xjb1887HQBJD+bxVw=="
},
"edge-lexer": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/edge-lexer/-/edge-lexer-4.0.8.tgz",
"integrity": "sha512-5DnQ6wy8Ebd3P/2XtwQryCeKgZrMEmxWz12YdjOhQb+UNq6OeXEY5AC6zaSYFpPlGCBCUB+Mz9U6ja2lkh20+Q==",
"requires": {
"edge-error": "^2.0.6"
}
},
"edge-parser": {
"version": "8.0.11",
"resolved": "https://registry.npmjs.org/edge-parser/-/edge-parser-8.0.11.tgz",
"integrity": "sha512-W3UDF9xWAMs+v7QE3J0QT5azqYWxwqUedWKWLTT1siEfl2Upg/zFE3IZ5PPOvXipFRZvW75QNxbhfK09+WrpZg==",
"requires": {
"acorn": "^8.4.1",
"astring": "^1.7.5",
"edge-error": "^2.0.6",
"edge-lexer": "^4.0.8",
"js-stringify": "^1.0.2"
}
},
"edge-supercharged": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/edge-supercharged/-/edge-supercharged-3.1.1.tgz",
"integrity": "sha512-Pxgst3UeR+0PWuTIG2QHuFgFe73TMoVMphRsa/bOmIvOkQ87cD7+VxiS9ph2KbA4djJ2ChbdgtbNiIvju5yXEw==",
"requires": {
"@poppinss/utils": "^3.1.3",
"slash": "^3.0.0"
}
},
"edge.js": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/edge.js/-/edge.js-5.3.1.tgz",
"integrity": "sha512-TWiPo7Unaww1fYll/zMANVma08q2WoG8j7g9iK3fed5AevD0XuBl8N2L9+vCE7TKJmTm/zNP5z8bKbfGWOTRbw==",
"requires": {
"@poppinss/inspect": "^1.0.1",
"@poppinss/utils": "^3.1.4",
"edge-error": "^2.0.5",
"edge-lexer": "^4.0.7",
"edge-parser": "^8.0.10",
"js-stringify": "^1.0.2",
"macroable": "^5.1.4",
"stringify-attributes": "^2.0.0"
},
"dependencies": {
"@poppinss/utils": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@poppinss/utils/-/utils-3.2.0.tgz",
"integrity": "sha512-gnqlrxE4zMvqW+LpviyCWCg4+RShCYCFyBdVTyg9ZZEEgPBV9bEY+YB5r/2klFrKx30k9nfClHVI2n8ZKmXgsw==",
"requires": {
"@types/bytes": "^3.1.1",
"@types/he": "^1.1.2",
"buffer-alloc": "^1.2.0",
"bytes": "^3.1.0",
"change-case": "^4.1.2",
"cuid": "^2.1.8",
"fs-readdir-recursive": "^1.1.0",
"he": "^1.2.0",
"kind-of": "^6.0.3",
"lodash": "^4.17.21",
"ms": "^2.1.3",
"pluralize": "^8.0.0",
"require-all": "^3.0.0",
"resolve-from": "^5.0.0",
"slugify": "^1.6.0",
"truncatise": "0.0.8"
}
},
"macroable": {
"version": "5.1.4",
"resolved": "https://registry.npmjs.org/macroable/-/macroable-5.1.4.tgz",
"integrity": "sha512-6yOJQT7QhYlJqhNWn/B2h+1ylsCnL8dMBmBpdnVNK+02PfQm13Ix4Szx4HiS3rp4a28EKckCGW27gtTZoYXYYQ=="
},
"slugify": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/slugify/-/slugify-1.6.0.tgz",
"integrity": "sha512-FkMq+MQc5hzYgM86nLuHI98Acwi3p4wX+a5BO9Hhw4JdK4L7WueIiZ4tXEobImPqBz2sVcV0+Mu3GRB30IGang=="
}
}
},
"editorconfig": { "editorconfig": {
"version": "0.15.3", "version": "0.15.3",
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz", "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
@ -3474,7 +3726,6 @@
"version": "1.12.0", "version": "1.12.0",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.12.0.tgz",
"integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==", "integrity": "sha512-VNX0QkHK3RsXVKr9KrlUv/FoTa0NdbYoHHl7uXHv2rzyHSlxjdNAKug2twd9luJxpcyNeAgf5iPPMutJO67Dfg==",
"dev": true,
"requires": { "requires": {
"reusify": "^1.0.4" "reusify": "^1.0.4"
} }
@ -3692,8 +3943,7 @@
"get-stream": { "get-stream": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="
"dev": true
}, },
"get-value": { "get-value": {
"version": "2.0.6", "version": "2.0.6",
@ -3775,6 +4025,24 @@
} }
} }
}, },
"got": {
"version": "11.8.2",
"resolved": "https://registry.npmjs.org/got/-/got-11.8.2.tgz",
"integrity": "sha512-D0QywKgIe30ODs+fm8wMZiAcZjypcCodPNuMz5H9Mny7RJ+IjJ10BdmGW7OM7fHXP+O7r6ZwapQ/YQmMSvB0UQ==",
"requires": {
"@sindresorhus/is": "^4.0.0",
"@szmarczak/http-timer": "^4.0.5",
"@types/cacheable-request": "^6.0.1",
"@types/responselike": "^1.0.0",
"cacheable-lookup": "^5.0.3",
"cacheable-request": "^7.0.1",
"decompress-response": "^6.0.0",
"http2-wrapper": "^1.0.0-beta.5.2",
"lowercase-keys": "^2.0.0",
"p-cancelable": "^2.0.0",
"responselike": "^2.0.0"
}
},
"graceful-fs": { "graceful-fs": {
"version": "4.2.8", "version": "4.2.8",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz",
@ -3935,6 +4203,11 @@
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
"dev": true "dev": true
}, },
"http-cache-semantics": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ=="
},
"http-errors": { "http-errors": {
"version": "1.7.3", "version": "1.7.3",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.3.tgz",
@ -3947,6 +4220,15 @@
"toidentifier": "1.0.0" "toidentifier": "1.0.0"
} }
}, },
"http2-wrapper": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
"integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
"requires": {
"quick-lru": "^5.1.1",
"resolve-alpn": "^1.0.0"
}
},
"https-proxy-agent": { "https-proxy-agent": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
@ -3962,6 +4244,14 @@
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"dev": true "dev": true
}, },
"ical-generator": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ical-generator/-/ical-generator-3.0.0.tgz",
"integrity": "sha512-PlDOOipgTlMzbfDDy+NJixAf5bzNb46wf0JXPkhnSjNQJc50y/XTOhOnQW/cp6tD+4ITHIMhkCkQ4CrUlDKMFQ==",
"requires": {
"uuid-random": "^1.3.2"
}
},
"iconv-lite": { "iconv-lite": {
"version": "0.4.24", "version": "0.4.24",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@ -4335,6 +4625,11 @@
"integrity": "sha512-SJcJNBg32dGgxhPtM0wQqxqV0ax9k/9TaUskGDSJkSFSQOEWWvQ3zzWdGQRIUry2j1zA5+ReH13t0Mf3StuVZA==", "integrity": "sha512-SJcJNBg32dGgxhPtM0wQqxqV0ax9k/9TaUskGDSJkSFSQOEWWvQ3zzWdGQRIUry2j1zA5+ReH13t0Mf3StuVZA==",
"dev": true "dev": true
}, },
"js-stringify": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
"integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds="
},
"js-tokens": { "js-tokens": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
@ -4351,6 +4646,11 @@
"esprima": "^4.0.0" "esprima": "^4.0.0"
} }
}, },
"json-buffer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
},
"json-parse-better-errors": { "json-parse-better-errors": {
"version": "1.0.2", "version": "1.0.2",
"resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
@ -4393,6 +4693,14 @@
"integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==",
"dev": true "dev": true
}, },
"keyv": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.0.3.tgz",
"integrity": "sha512-zdGa2TOpSZPq5mU6iowDARnMBZgtCqJ11dJROFi6tg6kTn4nuUdU09lFyLFSaHrWqpIJ+EBq4E8/Dc0Vx5vLdA==",
"requires": {
"json-buffer": "3.0.1"
}
},
"kind-of": { "kind-of": {
"version": "6.0.3", "version": "6.0.3",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
@ -4570,6 +4878,11 @@
"tslib": "^2.0.3" "tslib": "^2.0.3"
} }
}, },
"lowercase-keys": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
"integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA=="
},
"lru-cache": { "lru-cache": {
"version": "6.0.0", "version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
@ -4804,6 +5117,22 @@
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz",
"integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA=="
}, },
"mime-kind": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/mime-kind/-/mime-kind-3.0.0.tgz",
"integrity": "sha512-sx9lClVP7GXY2mO3aVDWTQLhfvAdDvNhGi3o3g7+ae3aKaoybeGbEIlnreoRKjrbDpvlPltlkIryxOtatojeXQ==",
"requires": {
"file-type": "^12.1.0",
"mime-types": "^2.1.24"
},
"dependencies": {
"file-type": {
"version": "12.4.2",
"resolved": "https://registry.npmjs.org/file-type/-/file-type-12.4.2.tgz",
"integrity": "sha512-UssQP5ZgIOKelfsaB5CuGAL+Y+q7EmONuiwF3N5HAH0t27rvrttgi6Ra9k/+DVaY9UF6+ybxu5pOXLUdA8N7Vg=="
}
}
},
"mime-types": { "mime-types": {
"version": "2.1.32", "version": "2.1.32",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz",
@ -4817,6 +5146,11 @@
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
}, },
"mimic-response": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ=="
},
"minimatch": { "minimatch": {
"version": "3.0.4", "version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
@ -4953,6 +5287,20 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
}, },
"multi-part": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/multi-part/-/multi-part-3.0.0.tgz",
"integrity": "sha512-pDbdYQ6DLDxAsD83w9R7r7rlW56cETL7hIB5bCWX7FJYw0K+kL5JwHr0I8tRk9lGeFcAzf+2OEzXWlG/4wCnFw==",
"requires": {
"mime-kind": "^3.0.0",
"multi-part-lite": "^1.0.0"
}
},
"multi-part-lite": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/multi-part-lite/-/multi-part-lite-1.0.0.tgz",
"integrity": "sha512-KxIRbBZZ45hoKX1ROD/19wJr0ql1bef1rE8Y1PCwD3PuNXV42pp7Wo8lEHYuAajoT4vfAFcd3rPjlkyEEyt1nw=="
},
"mustache": { "mustache": {
"version": "4.2.0", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
@ -5045,6 +5393,11 @@
"acorn-walk": "^8.0.2" "acorn-walk": "^8.0.2"
} }
}, },
"nodemailer": {
"version": "6.6.3",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.6.3.tgz",
"integrity": "sha512-faZFufgTMrphYoDjvyVpbpJcYzwyFnbAMmQtj1lVBYAUSm3SOy2fIdd9+Mr4UxPosBa0JRw9bJoIwQn+nswiew=="
},
"nopt": { "nopt": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz",
@ -5274,6 +5627,11 @@
} }
} }
}, },
"p-cancelable": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
"integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg=="
},
"p-defer": { "p-defer": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz",
@ -5794,7 +6152,6 @@
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": { "requires": {
"end-of-stream": "^1.1.0", "end-of-stream": "^1.1.0",
"once": "^1.3.1" "once": "^1.3.1"
@ -5830,6 +6187,11 @@
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.3.tgz", "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.3.tgz",
"integrity": "sha512-MaL/oqh02mhEo5m5J2rwsVL23Iw2PEaGVHgT2vFt8AAsr0lfvQA5dpXo9TPu0rz7tSBdUPgkbam0j/fj5ZM8yg==" "integrity": "sha512-MaL/oqh02mhEo5m5J2rwsVL23Iw2PEaGVHgT2vFt8AAsr0lfvQA5dpXo9TPu0rz7tSBdUPgkbam0j/fj5ZM8yg=="
}, },
"quick-lru": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
"integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA=="
},
"random-bytes": { "random-bytes": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
@ -6059,6 +6421,11 @@
"path-parse": "^1.0.6" "path-parse": "^1.0.6"
} }
}, },
"resolve-alpn": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
"integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="
},
"resolve-from": { "resolve-from": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@ -6070,6 +6437,14 @@
"integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
"dev": true "dev": true
}, },
"responselike": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz",
"integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==",
"requires": {
"lowercase-keys": "^2.0.0"
}
},
"restore-cursor": { "restore-cursor": {
"version": "3.1.0", "version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
@ -6088,8 +6463,7 @@
"reusify": { "reusify": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
"dev": true
}, },
"rev-hash": { "rev-hash": {
"version": "3.0.0", "version": "3.0.0",
@ -7047,6 +7421,11 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
}, },
"uuid-random": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/uuid-random/-/uuid-random-1.3.2.tgz",
"integrity": "sha512-UOzej0Le/UgkbWEO8flm+0y+G+ljUon1QWTEZOq1rnMAsxo2+SckbiZdKzAHHlVh6gJqI1TjC/xwgR50MuCrBQ=="
},
"v8-compile-cache": { "v8-compile-cache": {
"version": "2.3.0", "version": "2.3.0",
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",

View File

@ -36,8 +36,10 @@
"@adonisjs/core": "^5.3.2", "@adonisjs/core": "^5.3.2",
"@adonisjs/drive": "^2.0.6", "@adonisjs/drive": "^2.0.6",
"@adonisjs/lucid": "^15.0.3", "@adonisjs/lucid": "^15.0.3",
"@adonisjs/mail": "^7.2.4",
"@adonisjs/redis": "^7.0.9", "@adonisjs/redis": "^7.0.9",
"@adonisjs/repl": "^3.1.6", "@adonisjs/repl": "^3.1.6",
"@adonisjs/view": "^6.1.0",
"cloudinary": "^1.26.3", "cloudinary": "^1.26.3",
"luxon": "^1.28.0", "luxon": "^1.28.0",
"nanoid": "^3.1.25", "nanoid": "^3.1.25",

View File

@ -0,0 +1,4 @@
<h1>Your confirmation code for changing email</h1>
<p>
Code: {{ confirmationCode }}
</p>

View File

@ -2,6 +2,12 @@ import Route from '@ioc:Adonis/Core/Route';
Route.group(() => { Route.group(() => {
Route.get('/', 'Api/v1/MeController.show').middleware('role:admin,teacher,student').as('me.show'); Route.get('/', 'Api/v1/MeController.show').middleware('role:admin,teacher,student').as('me.show');
Route.patch('/email', 'Api/v1/MeController.changeEmail')
.middleware('role:admin,teacher,student')
.as('me.change-email');
Route.post('/email/change/confirm', 'Api/v1/MeController.changeEmailConfirm')
.middleware('role:admin,teacher,student')
.as('me.change-email-confirm');
Route.patch('/password', 'Api/v1/MeController.changePassword') Route.patch('/password', 'Api/v1/MeController.changePassword')
.middleware('role:admin,teacher,student') .middleware('role:admin,teacher,student')
.as('me.change-password'); .as('me.change-password');

View File

@ -1,18 +1,39 @@
{ {
"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,
"useDefineForClassFields": true, "useDefineForClassFields": true,
"paths": { "paths": {
"App/*": ["./app/*"], "App/*": [
"Config/*": ["./config/*"], "./app/*"
"Contracts/*": ["./contracts/*"], ],
"Database/*": ["./database/*"] "Config/*": [
"./config/*"
],
"Contracts/*": [
"./contracts/*"
],
"Database/*": [
"./database/*"
]
}, },
"types": ["@adonisjs/core", "@adonisjs/repl", "@adonisjs/lucid", "@adonisjs/auth", "@adonisjs/redis"] "types": [
"@adonisjs/core",
"@adonisjs/repl",
"@adonisjs/lucid",
"@adonisjs/auth",
"@adonisjs/redis",
"@adonisjs/mail",
"@adonisjs/view"
]
} }
} }