diff --git a/.eslintrc.js b/.eslintrc.cjs similarity index 100% rename from .eslintrc.js rename to .eslintrc.cjs diff --git a/.gitignore b/.gitignore index c0ebc85b..5a0a07d1 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,6 @@ sw.* # Custom user scripts /scripts/custom + +# Database +db.json diff --git a/README.md b/README.md index 77020ff0..7df24258 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ $ yarn install $ yarn dev # build for production and launch server (localhost:8800) -$ yarn build +$ yarn generate $ yarn start ``` diff --git a/api/app.js b/api/app.js new file mode 100644 index 00000000..0a383fa0 --- /dev/null +++ b/api/app.js @@ -0,0 +1,57 @@ +// Imports +import createError from 'http-errors' +import express from 'express' +import cors from 'cors' +import cookieParser from 'cookie-parser' + +// Authentication Import +import passport from 'passport' + +// Importing Routes +import baseRoutes from './router.js' + +// Development +const isDev = process.env.NODE_ENV === 'development' +console.log('[App] -> Development:', isDev) + +// Config +const PORT = process.env.PORT || 8800 // Default Port: 8800 + +// Express Init +const app = express() +if (isDev) app.use(cors()) // CORS policy only in dev +app.use(express.static('dist')) +app.use(express.json()) +app.use(express.urlencoded({ extended: true })) // for form data +app.use(cookieParser()) // Cookies +app.use(passport.initialize()) // Authentication + +// Router/Endpoints +const baseUrl = '/api/v1' +baseRoutes(app, baseUrl) + +// Catch 404 and forward to error handler +app.use((req, res, next) => { + next(createError(404)) +}) + +// Error handler +app.use((err, req, res, next) => { + console.error('Request Url:', req.originalUrl) + + // Set locals, only providing error in development + res.locals.message = err.message + res.locals.error = req.app.get('env') === 'development' ? err : {} + + // Render the error page + res.status(err.status || 500) + res.json({ + _status: 'error', + err + }) +}) + +// Listening on port +app.listen(PORT, () => { + console.log(`[App] -> App is running on ${PORT}`) +}) diff --git a/api/controllers/authentication.controller.js b/api/controllers/authentication.controller.js new file mode 100644 index 00000000..b34e700b --- /dev/null +++ b/api/controllers/authentication.controller.js @@ -0,0 +1,168 @@ +import { join } from 'path' +import crypto from 'crypto' +import fs from 'fs-extra' +import bcrypt from 'bcrypt' +import passport from 'passport' +import LocalStrategy from 'passport-local' +import JwtStrategy from 'passport-jwt' +import jwt from 'jsonwebtoken' +import User from '../models/user.js' + +// const authUserSecret = getAuthUserSecret() // process.env.AUTH_USER_SECRET +getAuthUserSecret() + +// Returning or if it not exists generating a authentication secret key +async function getAuthUserSecret() { + // Getting Env if available + const secret = process.env.AUTH_USER_SECRET || false + + // If Env variable is not existing, we will generate one + if (!secret) { + const generatedKey = crypto.randomBytes(256).toString('hex') + process.env.AUTH_USER_SECRET = generatedKey + + // Saving key in '.env' file + const filePath = join('.', '.env') + const content = `AUTH_USER_SECRET=${generatedKey}` + await fs.outputFile(filePath, content).catch((error) => { + console.error(error) + throw error + }) + return generatedKey + } + return secret +} + +// Setting up passport for email/password authentication +passport.use(new LocalStrategy.Strategy({ usernameField: 'email', passwordField: 'password' }, async function(email, password, done) { + await User.GetUser(email) + .then((user) => { + return user + }).then(async(user) => { + if (!user) { + return done(null, false, { message: 'Authentication failed' }) + } + const validation = await comparePasswords(password, user.password) + if (validation) { + return done(null, user) + } else { + return done(null, false, { message: 'Authentication failed' }) + } + }).catch((err) => { + return done(err) + }) +})) + +// Extracting JWT Token out of cookies +const tokenExtractor = function(req) { + let token = null + let reqCookie = null + let reqHeader = null + + // Extracting 'jwt' token from two different places + try { + if (req && req.cookies && req.cookies['auth._token.local']) { + reqCookie = req.cookies['auth._token.local'] + } else if (req.req && req.req.cookies && req.req.cookies['auth._token.local']) { + reqCookie = req.req.cookies['auth._token.local'] + } else if (req.headers && req.headers && req.headers.authorization) { + reqHeader = req.headers.authorization + } else if (req.req.headers && req.req.headers && req.req.headers.authorization) { + reqHeader = req.req.headers.authorization + } + } catch (error) { + // console.error(error) + return null + } + + if (reqCookie) { + const rawToken = reqCookie.toString() + token = rawToken.slice(rawToken.indexOf(' ') + 1, rawToken.length) + } else if (reqHeader) { + token = reqHeader.slice(reqHeader.indexOf(' ') + 1, reqHeader.length) + } + return token +} + +/* +const options = { + // tokenExtractor + // JwtStrategy.ExtractJwt.fromAuthHeaderAsBearerToken() + // JwtStrategy.ExtractJwt.fromExtractors([tokenExtractor, JwtStrategy.ExtractJwt.fromHeader('authorization'), JwtStrategy.ExtractJwt.fromAuthHeaderAsBearerToken()]) + jwtFromRequest: tokenExtractor, + secretOrKey: process.env.AUTH_USER_SECRET // authUserSecret +} +*/ + +// Setting up passport for JWT Token authentication +passport.use(new JwtStrategy.Strategy({ jwtFromRequest: tokenExtractor, secretOrKey: process.env.AUTH_USER_SECRET }, async function(jwtPayload, done) { + await User.GetUser(jwtPayload.email) // Or 'GetUser' - without 'User.' + .then((user) => { + if (user) { + return done(null, { + email: user.email + }) + } else { + return done(null, false, 'Failed') + } + }) + .catch((err) => { + console.error(err) + return done(err) + }) +})) + +/** + * Take a string and return a generated hash + * @name generatePasswordHash + * @function + * @memberof module:routers/auth + */ +async function generatePasswordHash(plainPassword) { + return await bcrypt.hash(plainPassword, 12) +} + +// Compares password from plaintext and hashed one +async function comparePasswords(plainPassword, hashedPassword) { + return await bcrypt.compare(plainPassword, hashedPassword) +} + +/** + * Returns generated token for authentication + * @name signUserToken + * @function + * @memberof module:routers/auth + */ +function signUserToken(user) { + return jwt.sign({ + id: user.id, + email: user.email + }, process.env.AUTH_USER_SECRET) // authUserSecret +} + +/** + * Proxy for CreateUser model function - creates a user in database + * @name CreateUser + * @function + * @memberof module:routers/auth + */ +async function CreateUser(user) { + return await User.CreateUser(user) +} + +/** + * Proxy for CountUsers model function - counts how many users registered, or returns false + * @name CountUsers + * @function + * @memberof module:routers/auth + */ +async function CountUsers() { + return await User.CountUsers() +} + +export default { + CreateUser, + CountUsers, + generatePasswordHash, + signUserToken +} diff --git a/server-middleware/controllers/scriptsController.js b/api/controllers/scripts.controller.js similarity index 92% rename from server-middleware/controllers/scriptsController.js rename to api/controllers/scripts.controller.js index 790573af..37ab970a 100644 --- a/server-middleware/controllers/scriptsController.js +++ b/api/controllers/scripts.controller.js @@ -1,14 +1,14 @@ // Imports -const path = require('path') -const fs = require('fs-extra') +import path from 'path' +import fs from 'fs-extra' // Middleware -const asyncHandler = require('../middleware/asyncHandler') // Middleware for handling errors on promise calls -const isCustomScript = require('../middleware/isCustomScript') // Testing if given 'path' is a 'custom path' -const zipDirectory = require('../middleware/zipDirectory') // Zipping file/folder middleware +import asyncHandler from '../middleware/asyncHandler.js' // Middleware for handling errors on promise calls +import isCustomScript from '../middleware/isCustomScript.js' // Testing if given 'path' is a 'custom path' +import zipDirectory from '../middleware/zipDirectory.js' // Zipping file/folder middleware // ChildProcess Spawn Import -const ChildProcessClass = require('../../classes/ChildProcessClass') +import ChildProcessClass from '../../classes/ChildProcessClass.js' const childProcessSpawn = new ChildProcessClass() // Script Directory @@ -20,7 +20,7 @@ const scriptPath = path.join('.', 'scripts') * @function * @memberof module:routers/scripts */ -exports.index = (req, res) => { +const index = (req, res) => { res.json({ _status: 'ok', info: 'Endpoint is set up.' @@ -33,7 +33,7 @@ exports.index = (req, res) => { * @function * @memberof module:routers/scripts */ -exports.list = asyncHandler(async(req, res, next) => { +const list = asyncHandler(async(req, res, next) => { // Generates unique random IDs for every folder/file const uniqueIds = [] let maxIds = 100 @@ -93,7 +93,7 @@ exports.list = asyncHandler(async(req, res, next) => { * @param {string} script - Query for script path. Exp.: ?script=scripts%5Ccustom%5Ctest.bat * @param {array} args - Query for arguments. Exp.: ?args=['a', 'b', 'c'] */ -exports.execute = asyncHandler(async(req, res, next) => { +const execute = asyncHandler(async(req, res, next) => { const { query } = req const scriptRaw = query.script const args = query.args || [] @@ -142,7 +142,7 @@ exports.execute = asyncHandler(async(req, res, next) => { * @param {string} name - Query for file name (just required for response). Exp.: ?name=test.bat * @param {string} type - Query for file type (just required for response). Exp.: ?type=file */ -exports.read = asyncHandler(async(req, res, next) => { +const read = asyncHandler(async(req, res, next) => { // Query Data const query = req.query const { id, name, type, path } = query @@ -176,7 +176,7 @@ exports.read = asyncHandler(async(req, res, next) => { * @param {string} path - Query for file path. Exp.: ?path=scripts%5Ccustom%5Ctest.bat * @param {string} name - Query for file name. Exp.: ?name=test.bat */ -exports.download = asyncHandler(async(req, res, next) => { +const download = asyncHandler(async(req, res, next) => { // Query Data const query = req.query const name = query.name @@ -215,7 +215,7 @@ exports.download = asyncHandler(async(req, res, next) => { * @memberof module:routers/scripts * @param {object} data - Object -> form data. Delivers script data: '{ path: "scripts/custom/...", script: { name: "test", ext: "bat", text: "echo test" }}' */ -exports.addFile = asyncHandler(async(req, res, next) => { +const addFile = asyncHandler(async(req, res, next) => { const data = req.body const script = data.script const file = `${script.name}.${script.ext}` @@ -259,7 +259,7 @@ exports.addFile = asyncHandler(async(req, res, next) => { * @memberof module:routers/scripts * @param {object} data - Object -> form data. Delivers folder data: '{ path: "scripts\custom", name: "test" }' */ -exports.addFolder = asyncHandler(async(req, res, next) => { +const addFolder = asyncHandler(async(req, res, next) => { const data = req.body const folderName = data.name const folderPath = data.path @@ -300,7 +300,7 @@ exports.addFolder = asyncHandler(async(req, res, next) => { * @memberof module:routers/scripts * @param {string} path - Query for file/folder path. Exp.: ?path=scripts\custom\test */ -exports.delete = asyncHandler(async(req, res, next) => { +const deleteFileOrFolder = asyncHandler(async(req, res, next) => { // Query Data const query = req.query const filePath = query.path @@ -363,7 +363,7 @@ exports.delete = asyncHandler(async(req, res, next) => { * @param {string} oldFile - Query for old file data. Exp.: ?oldFile: {"path":"scripts\\custom\\test.bat","name":"test.bat","id":71,"type":"file"} * @param {string} newFile - Query for new file data. Exp.: ?newFile: {"name":"new.bat","content":"echo test"} */ -exports.editFile = asyncHandler(async(req, res, next) => { +const editFile = asyncHandler(async(req, res, next) => { // Query Data const query = req.query const oldFile = JSON.parse(query.oldFile) @@ -430,7 +430,7 @@ exports.editFile = asyncHandler(async(req, res, next) => { * @param {string} oldFolder - Query for old file data. Exp.: ?oldFolder: {"path":"scripts\\custom\\test","name":"test"} * @param {string} newFolder - Query for new file data. Exp.: ?newFolder: {"name":"new"} */ -exports.editFolder = asyncHandler(async(req, res, next) => { +const editFolder = asyncHandler(async(req, res, next) => { // Query Data const query = req.query const oldFolder = JSON.parse(query.oldFolder) @@ -472,3 +472,16 @@ exports.editFolder = asyncHandler(async(req, res, next) => { }) } }) + +export default { + index, + list, + execute, + read, + download, + addFile, + addFolder, + deleteFileOrFolder, + editFile, + editFolder +} diff --git a/server-middleware/middleware/asyncHandler.js b/api/middleware/asyncHandler.js similarity index 90% rename from server-middleware/middleware/asyncHandler.js rename to api/middleware/asyncHandler.js index 208fd08a..23c877f7 100644 --- a/server-middleware/middleware/asyncHandler.js +++ b/api/middleware/asyncHandler.js @@ -6,4 +6,4 @@ const asyncUtil = (fn) => return Promise.resolve(fnReturn).catch(next) } -module.exports = asyncUtil +export default asyncUtil diff --git a/server-middleware/middleware/isCustomScript.js b/api/middleware/isCustomScript.js similarity index 94% rename from server-middleware/middleware/isCustomScript.js rename to api/middleware/isCustomScript.js index 1fc03c45..3df99fae 100644 --- a/server-middleware/middleware/isCustomScript.js +++ b/api/middleware/isCustomScript.js @@ -10,4 +10,4 @@ const isCustomScript = (path) => { return /^scripts\\custom\\/gm.test(path) /* win path */ || /^scripts\/custom\//gm.test(path) /* linux path */ } -module.exports = isCustomScript +export default isCustomScript diff --git a/server-middleware/middleware/zipDirectory.js b/api/middleware/zipDirectory.js similarity index 87% rename from server-middleware/middleware/zipDirectory.js rename to api/middleware/zipDirectory.js index ce1e1f0e..47c35f97 100644 --- a/server-middleware/middleware/zipDirectory.js +++ b/api/middleware/zipDirectory.js @@ -1,5 +1,5 @@ -const fs = require('fs-extra') -const archiver = require('archiver') +import fs from 'fs-extra' +import archiver from 'archiver' /** * Middleware: Zipping a given file/folder @@ -24,4 +24,4 @@ const zipDirectory = (source, out) => { }) } -module.exports = zipDirectory +export default zipDirectory diff --git a/api/models/user.js b/api/models/user.js new file mode 100644 index 00000000..bda118ce --- /dev/null +++ b/api/models/user.js @@ -0,0 +1,49 @@ +import { join } from 'path' +import { Low, JSONFile } from 'lowdb' + +// Use JSON file for storage +const file = join('.', 'db.json') +const adapter = new JSONFile(file) +const db = new Low(adapter) + +// Initialize DB and set users data +async function init() { +// Read data from JSON file, this will set db.data content + await db.read() + + // If file.json doesn't exist, db.data will be null + // Set default data + db.data ||= { users: [] } +} +init() + +// LowDb: Writing User to database (db.json) +async function CreateUser(userData) { + // Create items + write db.data content to db.json + const user = db.data.users.push(userData) + await db.write() + return user +} + +// LowDb: Getting user from database +async function GetUser(email) { + // Read data from JSON file + const user = db.data.users.find((user) => user.email === email) + return user +} + +// LowDb: Counting existing users in database or returns false +async function CountUsers() { + // Read data from JSON file + const users = db.data.users + if (users && Array.isArray(users)) { + return db.data.users.length + } + return false +} + +export default { + CreateUser, + GetUser, + CountUsers +} diff --git a/api/router.js b/api/router.js new file mode 100644 index 00000000..5fadad72 --- /dev/null +++ b/api/router.js @@ -0,0 +1,29 @@ +// Authentication Import +import passport from 'passport' + +// Importing Routes +import indexRouter from './routes/index.js' +import helpRouter from './routes/help.js' +import authRouter from './routes/authentication.js' +import scriptsRouter from './routes/scripts.js' + +/** + * middleware for checking authorization with jwt + */ +function authorized(request, response, next) { + try { + passport.authenticate('jwt', { session: false })(request, response, next) + } catch (error) { + next(error) + } +} + +// Exporting Base Routes +export default function(app, baseUrl) { + app.use(baseUrl + '/', indexRouter) // Index + app.use(baseUrl + '/help', helpRouter) // Help + app.use(baseUrl + '/auth', authRouter) // Authentication + app.use(baseUrl + '/scripts', authorized, scriptsRouter) // Scripts + // app.use(baseUrl + '/scripts', passport.authenticate('jwt', { session: false }, scriptsRouter)) // Scripts + // app.use(baseUrl + '/scripts', scriptsRouter) // Scripts +} diff --git a/api/routes/authentication.js b/api/routes/authentication.js new file mode 100644 index 00000000..dc74ae25 --- /dev/null +++ b/api/routes/authentication.js @@ -0,0 +1,114 @@ +// Imports +import express from 'express' +import passport from 'passport' + +// Controller +import Controller from '../controllers/authentication.controller.js' + +// Routes +const router = express.Router() + +/* + * Router: Baseurl -> '/auth/..' +*/ + +// User Login Route +router.post('/login', (req, res) => { + passport.authenticate('local', { session: false }, (err, user, message) => { + if (err) { + // you should log it + return res.status(500).json({ + _status: 'error', + info: 'An error has occurred', + err + }) + } else if (!user) { + // you should log it + return res.status(403).json({ + _status: 'failed', + info: 'Login failed', + message: message.message + }) + } else { + const token = Controller.signUserToken(user) + return res.json({ token }) + } + })(req, res) +}) + +// Validates correctness of the token when a user visits restricted pages on the frontend +router.get('/user', async(req, res) => { + // console.log(req.cookies['auth._token.local']) + passport.authenticate('jwt', { session: false }, (err, user, message) => { + if (err) { + // you should log it + return res.status(400).json({ + _status: 'error', + info: 'An error has occurred', + err + }) + } else if (!user) { + // you should log it + return res.status(403).json({ + _status: 'failed', + info: 'Validation failed', + message: message.message + }) + } else { + return res.json({ user }) + } + })(res, req) +}) + +// Register a User and write user data into database +router.post('/register', async(req, res) => { + const password = req.body.password + const email = req.body.email + + /* TODO: IF AT LEAST ONE USER IS ALREADY REGISTERED, ONLY A LOGGED IN USER (ADMIN) SHOULD REGISTER ADDITIONAL USER!!! */ + + // Checks if a user is already registered + const users = await Controller.CountUsers() + if (users && users > 0) { + return res.status(403).json({ + _status: 'forbidden', + info: 'There is already one user registered!', + message: 'Only one user is allowed right now!' + }) + } + + // Hashing password and creating user data + const hashedPassword = await Controller.generatePasswordHash(password) + await Controller.CreateUser({ email, password: hashedPassword }) + .then(() => { + res.json({ + _status: 'ok', + info: 'User created.', + message: 'An account has been created!' + }) + }).catch((err) => { + throw err + }) +}) + +// Looks if at least one user is already registered +router.get('/registered-users', async(req, res) => { + // Checks if a user is already registered + const users = await Controller.CountUsers() + if (users && users > 0) { + return res.json({ + _status: 'ok', + info: 'There is at least one user registered!', + message: 'Registration not available', + registration: false + }) + } + return res.json({ + _status: 'ok', + info: 'No user is registered right now', + message: 'Registration available', + registration: true + }) +}) + +export default router diff --git a/server-middleware/routes/help.js b/api/routes/help.js similarity index 82% rename from server-middleware/routes/help.js rename to api/routes/help.js index 4718515d..c8336276 100644 --- a/server-middleware/routes/help.js +++ b/api/routes/help.js @@ -1,5 +1,5 @@ // Express -const express = require('express') +import express from 'express' const router = express.Router() // Route: '/help' -> just for testing purpose right now @@ -11,4 +11,4 @@ router.all('/', (req, res, next) => { }) }) -module.exports = router +export default router diff --git a/server-middleware/routes/index.js b/api/routes/index.js similarity index 77% rename from server-middleware/routes/index.js rename to api/routes/index.js index 6a0c4ed8..931b6630 100644 --- a/server-middleware/routes/index.js +++ b/api/routes/index.js @@ -1,5 +1,5 @@ // Express -const express = require('express') +import express from 'express' const router = express.Router() // Route: '/' -> REST Api index endpoint @@ -10,4 +10,4 @@ router.all('/', (req, res, next) => { }) }) -module.exports = router +export default router diff --git a/api/routes/scripts.js b/api/routes/scripts.js new file mode 100644 index 00000000..1370823c --- /dev/null +++ b/api/routes/scripts.js @@ -0,0 +1,22 @@ +// Express +import express from 'express' + +// Controller +import Controller from '../controllers/scripts.controller.js' + +// Router +const router = express.Router() + +// Router: '/scripts/..' +router.all('/', Controller.index) /* ALL index. */ +router.get('/list', Controller.list) /* GET list of scripts. */ +router.post('/execute', Controller.execute) /* POST: executes a script/file. */ +router.get('/read', Controller.read) /* GET a file and returns data. */ +router.get('/download', Controller.download) /* GET: downloading a file/folder. */ +router.post('/add/file', Controller.addFile) /* POST: adding a file to host. */ +router.post('/add/folder', Controller.addFolder) /* POST: adding a folder to host. */ +router.post('/delete', Controller.deleteFileOrFolder) /* POST: deleting a given file/folder. */ +router.post('/edit/file', Controller.editFile) /* POST: editing a file. */ +router.post('/edit/folder', Controller.editFolder) /* POST: editing a folder. */ + +export default router diff --git a/classes/ChildProcessClass.js b/classes/ChildProcessClass.js index 930e8953..3e1d729f 100644 --- a/classes/ChildProcessClass.js +++ b/classes/ChildProcessClass.js @@ -1,5 +1,5 @@ // Imports -const { execFile } = require('child_process') +import { execFile } from 'child_process' const isWin = process.platform === 'win32' const isLinux = process.platform === 'linux' @@ -158,4 +158,4 @@ class ChildProcessClass { } } } -module.exports = ChildProcessClass +export default ChildProcessClass diff --git a/components/display/AppUpdateChip.vue b/components/display/AppUpdateChip.vue new file mode 100644 index 00000000..b3880f27 --- /dev/null +++ b/components/display/AppUpdateChip.vue @@ -0,0 +1,42 @@ + + + diff --git a/components/display/AppVersion.vue b/components/display/AppVersion.vue index ede6b3f3..93766de0 100644 --- a/components/display/AppVersion.vue +++ b/components/display/AppVersion.vue @@ -26,13 +26,14 @@ {{ currentVersion }} - {{ isUpToDate ? 'App is up to date' : 'Newer version available' }} + {{ isUpToDate ? 'App is up to date' : `New version: ${latestVersion}` }} diff --git a/components/layout/Header.vue b/components/layout/Header.vue index d88a8f84..22e5797b 100644 --- a/components/layout/Header.vue +++ b/components/layout/Header.vue @@ -6,26 +6,23 @@ - - - mdi-cogs - - + + + mdi-cogs + diff --git a/ecosystem.config.js b/ecosystem.config.js index 343285a0..57f494cc 100644 --- a/ecosystem.config.js +++ b/ecosystem.config.js @@ -5,7 +5,7 @@ module.exports = { name: pkg.name, exec_mode: 'cluster', instances: 1, // 'max' Or a number of instances - script: './node_modules/nuxt/bin/nuxt.js', + script: './api/app.js', // './node_modules/nuxt/bin/nuxt.js', args: 'start' } ] diff --git a/nuxt.config.js b/nuxt.config.js index cecd016f..9aa8f86d 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -1,19 +1,13 @@ // import colors from 'vuetify/es5/util/colors' import pkg from './package.json' +// Development const isDev = process.env.NODE_ENV !== 'production' // Server Settings -/* -const server = { - host: isDev ? 'localhost' : '0.0.0.0', // dev: localhost, production: os-ip-adress - port: isDev ? 3000 : 8800, // dev: 3000, production: 8800 - timing: false -} -*/ const server = { server: { - host: '0.0.0.0', // dev: localhost, production: os-ip-adress + host: '0.0.0.0', // os-ip-adress port: isDev ? 3000 : 8800, // dev: 3000, production: 8800 timing: false } @@ -33,8 +27,9 @@ export default { // Adding env variables ...env, - // Nuxt target - target: 'server', + // Nuxt target -> Client Side Rendering (SPA) + target: 'static', + ssr: false, // Global page headers: https://go.nuxtjs.dev/config-head head: { @@ -78,6 +73,9 @@ export default { modules: [ // https://go.nuxtjs.dev/axios '@nuxtjs/axios', + // https://auth.nuxtjs.org/ + // '@nuxtjs/auth', + '@nuxtjs/auth-next', // https://github.com/Maronato/vue-toastification ['vue-toastification/nuxt', { position: 'bottom-right', @@ -92,24 +90,44 @@ export default { }] ], - // Axios module configuration: https://go.nuxtjs.dev/config-axios - axios: { - browserBaseURL: '/api/v1' + // Global Middleware + router: { + middleware: ['auth'] // Pages accessible after login. If one page should be accessible without login, set 'auth: false' in page }, - /* - publicRuntimeConfig: { - axios: { - browserBaseURL: process.env.BROWSER_BASE_URL - } + // Axios module configuration: https://go.nuxtjs.dev/config-axios + axios: { + baseURL: isDev ? 'http://localhost:8800/api/v1' : '/api/v1' + // browserBaseURL: '/api/v1' }, - privateRuntimeConfig: { - axios: { - baseURL: process.env.BASE_URL + // Nuxt authentication modul: https://auth.nuxtjs.org/ + auth: { + localStorage: true, + strategies: { + local: { + endpoints: { + login: { + url: '/auth/login', + method: 'post', + propertyName: 'token' + }, + logout: false, + user: { + url: '/auth/user', + method: 'get', + propertyName: false + } + } + } + }, + redirect: { + login: '/user/login', + logout: '/', + callback: '/user/login', + home: '/' } }, - */ // Vuetify module configuration: https://go.nuxtjs.dev/config-vuetify vuetify: { @@ -132,11 +150,6 @@ export default { } }, - // Serverside Middleware -> REST Api - serverMiddleware: [ - { path: '/api/v1', handler: '~/server-middleware/rest-api.js' } - ], - // Build Configuration: https://go.nuxtjs.dev/config-build build: {} } diff --git a/package.json b/package.json index 719c3f02..27ffef06 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "pi-control", "productName": "Pi-Control 🐱‍👤", - "version": "0.0.1-alpha.1", + "version": "0.0.1-alpha.2", "description": "Pi-Control helps with gathering information, as well as to simplify controlling your raspberry pi.", "author": "borsTiHD", "license": "MIT", @@ -9,14 +9,18 @@ "type": "git", "url": "https://github.com/borsTiHD/pi-control" }, + "type": "module", "scripts": { - "dev": "nuxt", - "build": "nuxt build", - "start": "nuxt start", + "dev:nuxt": "nuxt", + "dev:api": "node -r dotenv/config ./api/app.js", + "dev": "cross-env NODE_ENV=development concurrently \"yarn dev:api\" \"yarn dev:nuxt\"", + "generate": "nuxt generate", + "start": "node -r dotenv/config ./api/app.js", "lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .", "lint": "yarn lint:js" }, "dependencies": { + "@nuxtjs/auth-next": "5.0.0-1621716493.b9b36c6", "@nuxtjs/axios": "^5.13.3", "core-js": "^3.9.1", "nuxt": "^2.15.6" @@ -27,14 +31,24 @@ "@nuxtjs/vuetify": "^1.11.3", "archiver": "^5.3.0", "babel-eslint": "^10.1.0", + "bcrypt": "^5.0.1", + "concurrently": "^6.2.0", + "cookie-parser": "^1.4.5", "cors": "^2.8.5", + "cross-env": "^7.0.3", + "dotenv": "^10.0.0", "eslint": "^7.22.0", "eslint-plugin-nuxt": "^2.0.0", "eslint-plugin-vue": "^7.7.0", "express": "^4.17.1", "fs-extra": "^10.0.0", "idb": "^6.0.0", + "jsonwebtoken": "^8.5.1", + "lowdb": "^2.1.0", "moment": "^2.29.1", + "passport": "^0.4.1", + "passport-jwt": "^4.0.0", + "passport-local": "^1.0.0", "vue-toastification": "^1.7.11" } } diff --git a/pages/about.vue b/pages/about.vue index a2355485..3924e9ef 100644 --- a/pages/about.vue +++ b/pages/about.vue @@ -47,6 +47,7 @@ import pkg from '~~/package.json' export default { name: 'About', + auth: false, data() { return { continueRoute: '/dashboard' diff --git a/pages/index.vue b/pages/index.vue index 814663bc..eed871e5 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -15,6 +15,7 @@ diff --git a/pages/user/register.vue b/pages/user/register.vue new file mode 100644 index 00000000..ee8875d2 --- /dev/null +++ b/pages/user/register.vue @@ -0,0 +1,103 @@ + + + diff --git a/server-middleware/rest-api.js b/server-middleware/rest-api.js deleted file mode 100644 index f42dbb72..00000000 --- a/server-middleware/rest-api.js +++ /dev/null @@ -1,36 +0,0 @@ -// Imports -const createError = require('http-errors') -const express = require('express') - -// Importing Routes -const indexRouter = require('./routes/index') -const helpRouter = require('./routes/help') -const scriptsRouter = require('./routes/scripts') - -// Express Init -const app = express() -app.use(express.json()) -app.use(express.urlencoded({ extended: true })) // for form data - -// Routes/Endpoints: -app.use('/', indexRouter) // Index -app.use('/help', helpRouter) // Help -app.use('/scripts', scriptsRouter) // Scripts - -// Catch 404 and forward to error handler -app.use((req, res, next) => { - next(createError(404)) -}) - -// Error handler -app.use((err, req, res, next) => { - // Set locals, only providing error in development - res.locals.message = err.message - res.locals.error = req.app.get('env') === 'development' ? err : {} - - // Render the error page - res.status(err.status || 500) - res.render('error') -}) - -module.exports = app diff --git a/server-middleware/routes/scripts.js b/server-middleware/routes/scripts.js deleted file mode 100644 index 2943a0c6..00000000 --- a/server-middleware/routes/scripts.js +++ /dev/null @@ -1,20 +0,0 @@ -// Express -const express = require('express') -const router = express.Router() - -// Controller -const controller = require('../controllers/scriptsController') - -// Router: '/scripts/..' -router.all('/', controller.index) /* ALL index. */ -router.get('/list', controller.list) /* GET list of scripts. */ -router.post('/execute', controller.execute) /* POST: executes a script/file. */ -router.get('/read', controller.read) /* GET a file and returns data. */ -router.get('/download', controller.download) /* GET: downloading a file/folder. */ -router.post('/add/file', controller.addFile) /* POST: adding a file to host. */ -router.post('/add/folder', controller.addFolder) /* POST: adding a folder to host. */ -router.post('/delete', controller.delete) /* POST: deleting a given file/folder. */ -router.post('/edit/file', controller.editFile) /* POST: editing a file. */ -router.post('/edit/folder', controller.editFolder) /* POST: editing a folder. */ - -module.exports = router diff --git a/static/README.md b/static/README.md deleted file mode 100644 index cf004353..00000000 --- a/static/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# STATIC - -**This directory is not required, you can delete it if you don't want to use it.** - -This directory contains your static files. -Each file inside this directory is mapped to `/`. -Thus you'd want to delete this README.md before deploying to production. - -Example: `/static/robots.txt` is mapped as `/robots.txt`. - -More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/assets#static). diff --git a/static/v.png b/static/v.png deleted file mode 100644 index a2ce2353..00000000 Binary files a/static/v.png and /dev/null differ diff --git a/static/vuetify-logo.svg b/static/vuetify-logo.svg deleted file mode 100644 index 145b6d13..00000000 --- a/static/vuetify-logo.svg +++ /dev/null @@ -1 +0,0 @@ -Artboard 46 diff --git a/store/index.js b/store/index.js index 95acec76..83b4b7d9 100644 --- a/store/index.js +++ b/store/index.js @@ -1,12 +1,16 @@ // Root Store export const state = () => ({ - newRelease: false + newRelease: false, + releaseData: null }) // Sync functions for setting data export const mutations = { setNewRelease(state, payload) { state.newRelease = payload + }, + setReleaseData(state, payload) { + state.releaseData = payload } } @@ -14,12 +18,18 @@ export const mutations = { export const actions = { setNewRelease({ commit }, payload) { commit('setNewRelease', payload) + }, + setReleaseData({ commit }, payload) { + commit('setReleaseData', payload) } } // Getting computed data export const getters = { - getNewRelease(state) { + isNewRelease(state) { return state.newRelease + }, + getReleaseData(state) { + return state.releaseData } } diff --git a/yarn.lock b/yarn.lock index 5dfea912..18aba87e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -939,6 +939,21 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@mapbox/node-pre-gyp@^1.0.0": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz#2a0b32fcb416fb3f2250fd24cb2a81421a4f5950" + integrity sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA== + dependencies: + detect-libc "^1.0.3" + https-proxy-agent "^5.0.0" + make-dir "^3.1.0" + node-fetch "^2.6.1" + nopt "^5.0.0" + npmlog "^4.1.2" + rimraf "^3.0.2" + semver "^7.3.4" + tar "^6.1.0" + "@nodelib/fs.scandir@2.1.4": version "2.1.4" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69" @@ -1285,7 +1300,22 @@ webpack-node-externals "^3.0.0" webpackbar "^4.0.0" -"@nuxtjs/axios@^5.13.3": +"@nuxtjs/auth-next@5.0.0-1621716493.b9b36c6": + version "5.0.0-1621716493.b9b36c6" + resolved "https://registry.yarnpkg.com/@nuxtjs/auth-next/-/auth-next-5.0.0-1621716493.b9b36c6.tgz#43e30dbfa9da1f327f7fafb00f54edcc006eb88d" + integrity sha512-ovE/cyEyiSr6ckPKJ2xbDdtKFpqwli1xyOK10w+A3W62GFZSX39JqNR6ZGyuJxYWbmywXyU2ZIjEpeceQ1+rug== + dependencies: + "@nuxtjs/axios" "^5.13.0" + axios "^0.21.1" + body-parser "^1.19.0" + consola "^2.15.3" + cookie "^0.4.1" + defu "^3.2.2" + hasha "^5.2.2" + jwt-decode "^3.1.2" + requrl "^3.0.2" + +"@nuxtjs/axios@^5.13.0", "@nuxtjs/axios@^5.13.3": version "5.13.4" resolved "https://registry.yarnpkg.com/@nuxtjs/axios/-/axios-5.13.4.tgz#32ef656b7fdec1e53acdfdff6fb1844a1698af1e" integrity sha512-RLDctJLm2erJhwKnnmII6vDmH4BLZ6mca/ndFJyamPlB9uzIVNyat2Dw+FYlJSJIDI1Mfp3NntipUiSGUqrXiw== @@ -1742,6 +1772,11 @@ resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" @@ -1775,6 +1810,13 @@ acorn@^8.0.4: resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0" integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg== +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -1897,7 +1939,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -aproba@^1.1.1: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== @@ -1931,6 +1973,14 @@ archiver@^5.3.0: tar-stream "^2.2.0" zip-stream "^4.1.0" +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + arg@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.0.tgz#a20e2bb5710e82950a516b3f933fee5ed478be90" @@ -2149,6 +2199,14 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +bcrypt@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-5.0.1.tgz#f1a2c20f208e2ccdceea4433df0c8b2c54ecdf71" + integrity sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw== + dependencies: + "@mapbox/node-pre-gyp" "^1.0.0" + node-addon-api "^3.1.0" + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -2195,7 +2253,7 @@ bn.js@^5.0.0, bn.js@^5.1.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== -body-parser@1.19.0: +body-parser@1.19.0, body-parser@^1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== @@ -2343,6 +2401,11 @@ buffer-crc32@^0.2.1, buffer-crc32@^0.2.13: resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -2685,6 +2748,15 @@ cli-width@^3.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + coa@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/coa/-/coa-2.0.2.tgz#43f6c21151b4ef2bf57187db0d73de229e3e7ec3" @@ -2694,6 +2766,11 @@ coa@^2.0.2: chalk "^2.4.1" q "^1.1.2" +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -2817,6 +2894,21 @@ concat-stream@^1.5.0: readable-stream "^2.2.2" typedarray "^0.0.6" +concurrently@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-6.2.0.tgz#587e2cb8afca7234172d8ea55176088632c4c56d" + integrity sha512-v9I4Y3wFoXCSY2L73yYgwA9ESrQMpRn80jMcqMgHx720Hecz2GZAvTI6bREVST6lkddNypDKRN22qhK0X8Y00g== + dependencies: + chalk "^4.1.0" + date-fns "^2.16.1" + lodash "^4.17.21" + read-pkg "^5.2.0" + rxjs "^6.6.3" + spawn-command "^0.0.2-1" + supports-color "^8.1.0" + tree-kill "^1.2.2" + yargs "^16.2.0" + connect@^3.7.0: version "3.7.0" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" @@ -2837,6 +2929,11 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + consolidate@^0.15.1: version "0.15.1" resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.15.1.tgz#21ab043235c71a07d45d9aad98593b0dba56bab7" @@ -2876,6 +2973,14 @@ convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" +cookie-parser@^1.4.5: + version "1.4.5" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.5.tgz#3e572d4b7c0c80f9c61daf604e4336831b5d1d49" + integrity sha512-f13bPUj/gG/5mDr+xLmSxxDsB9DQiTIfhJS/sqjrmfAWiAN+x2O4i/XguTL9yDZ+/IFDanJ+5x7hC4CXT9Tdzw== + dependencies: + cookie "0.4.0" + cookie-signature "1.0.6" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -2891,6 +2996,11 @@ cookie@^0.3.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= +cookie@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -3008,7 +3118,14 @@ create-require@^1.1.1: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-env@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-7.0.3.tgz#865264b29677dc015ba8418918965dd232fc54cf" + integrity sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw== + dependencies: + cross-spawn "^7.0.1" + +cross-spawn@^7.0.1, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -3239,6 +3356,11 @@ cyclist@^1.0.1: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= +date-fns@^2.16.1: + version "2.21.3" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.21.3.tgz#8f5f6889d7a96bbcc1f0ea50239b397a83357f9b" + integrity sha512-HeYdzCaFflc1i4tGbj7JKMjM4cKGYoyxwcIIkHzNgCkX8xXDNJDZXgDDVchIWpN4eQc3lH37WarduXFZJOtxfw== + de-indent@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" @@ -3251,6 +3373,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: dependencies: ms "2.0.0" +debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -3258,13 +3387,6 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== - dependencies: - ms "2.1.2" - decache@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/decache/-/decache-4.6.0.tgz#87026bc6e696759e82d57a3841c4e251a30356e8" @@ -3336,6 +3458,11 @@ defu@^5.0.0: resolved "https://registry.yarnpkg.com/defu/-/defu-5.0.0.tgz#5768f0d402a555bfc4c267246b20f82ce8b5a10b" integrity sha512-VHg73EDeRXlu7oYWRmmrNp/nl7QkdXUxkQQKig0Zk8daNmm84AbGoC8Be6/VVLJEKxn12hR0UBmz8O+xQiAPKQ== +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -3364,6 +3491,11 @@ detect-indent@^5.0.0: resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= +detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + devalue@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/devalue/-/devalue-2.0.1.tgz#5d368f9adc0928e47b77eea53ca60d2f346f9762" @@ -3484,6 +3616,11 @@ dot-prop@^5.2.0: dependencies: is-obj "^2.0.0" +dotenv@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" + integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== + dotenv@^9.0.2: version "9.0.2" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-9.0.2.tgz#dacc20160935a37dea6364aa1bef819fb9b6ab05" @@ -3504,6 +3641,13 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -4361,11 +4505,30 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + get-intrinsic@^1.0.2, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" @@ -4533,6 +4696,11 @@ has-symbols@^1.0.1, has-symbols@^1.0.2: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -4598,6 +4766,14 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hasha@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.2.2.tgz#a48477989b3b327aea3c04f53096d816d97522a1" + integrity sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ== + dependencies: + is-stream "^2.0.0" + type-fest "^0.8.0" + he@1.2.0, he@^1.1.0, he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -4742,6 +4918,14 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + human-signals@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" @@ -5046,6 +5230,13 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -5280,6 +5471,44 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" +jsonwebtoken@^8.2.0, jsonwebtoken@^8.5.1: + version "8.5.1" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz#00e71e0b8df54c2121a1f26137df2280673bcc0d" + integrity sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w== + dependencies: + jws "^3.2.2" + lodash.includes "^4.3.0" + lodash.isboolean "^3.0.3" + lodash.isinteger "^4.0.4" + lodash.isnumber "^3.0.3" + lodash.isplainobject "^4.0.6" + lodash.isstring "^4.0.1" + lodash.once "^4.0.0" + ms "^2.1.1" + semver "^5.6.0" + +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + +jwt-decode@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59" + integrity sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A== + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -5443,11 +5672,36 @@ lodash.flatten@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= +lodash.includes@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f" + integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8= + +lodash.isboolean@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6" + integrity sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY= + +lodash.isinteger@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz#619c0af3d03f8b04c31f5882840b77b11cd68343" + integrity sha1-YZwK89A/iwTDH1iChAt3sRzWg0M= + +lodash.isnumber@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc" + integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w= + lodash.isplainobject@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= +lodash.isstring@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" + integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= + lodash.kebabcase@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" @@ -5458,6 +5712,11 @@ lodash.memoize@^4.1.2: resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= +lodash.once@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" + integrity sha1-DdOXEhPHxW34gJd9UEyI+0cal6w= + lodash.template@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" @@ -5493,6 +5752,13 @@ lodash@^4.15.0, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17. resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== +lowdb@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lowdb/-/lowdb-2.1.0.tgz#c8063e228b5ab3e082ece90e0512537ecb6e1e2a" + integrity sha512-F4Go8/V37gAidTR3c5poyjprOpZSDNSLJVOmI0ny4D4q9rC37OkBhlzX0bqj7LZlT3UIj4FchmZrrSw7qY+eGQ== + dependencies: + steno "^1.0.0" + lower-case@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" @@ -5920,6 +6186,11 @@ no-case@^3.0.4: lower-case "^2.0.2" tslib "^2.0.3" +node-addon-api@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.0.tgz#7028b56a7eb572b73873aed731a7f9c9365f5ee4" + integrity sha512-kcwSAWhPi4+QzAtsL2+2s/awvDo2GKLsvMCwNRxb5BUshteXU8U97NCyvQDsGKs/m0He9WcG4YWew/BnuLx++w== + node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" @@ -5983,6 +6254,13 @@ node-res@^5.0.1: on-finished "^2.3.0" vary "^1.1.2" +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -6032,6 +6310,16 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npmlog@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + nth-check@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -6051,6 +6339,11 @@ num2fraction@^1.2.2: resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + nuxt@^2.15.6: version "2.15.6" resolved "https://registry.yarnpkg.com/nuxt/-/nuxt-2.15.6.tgz#628ff86d57c1d4671802777635ce7fd2c24f9091" @@ -6375,6 +6668,34 @@ pascalcase@^0.1.1: resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= +passport-jwt@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.0.tgz#7f0be7ba942e28b9f5d22c2ebbb8ce96ef7cf065" + integrity sha512-BwC0n2GP/1hMVjR4QpnvqA61TxenUMlmfNjYNgK0ZAs0HK4SOQkHcSv4L328blNTLtHq7DbmvyNJiH+bn6C5Mg== + dependencies: + jsonwebtoken "^8.2.0" + passport-strategy "^1.0.0" + +passport-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-local/-/passport-local-1.0.0.tgz#1fe63268c92e75606626437e3b906662c15ba6ee" + integrity sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4= + dependencies: + passport-strategy "1.x.x" + +passport-strategy@1.x.x, passport-strategy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + integrity sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ= + +passport@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.4.1.tgz#941446a21cb92fc688d97a0861c38ce9f738f270" + integrity sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg== + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + path-browserify@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" @@ -6434,6 +6755,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= + pbkdf2@^3.0.3: version "3.1.2" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" @@ -7439,7 +7765,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -7581,6 +7907,11 @@ repeat-string@^1.6.1: resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" @@ -7591,6 +7922,11 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= +requrl@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/requrl/-/requrl-3.0.2.tgz#d376104193b02a2d874dde68454c2db2dfeb0fac" + integrity sha512-f3gjR6d8MhOpn46PP+DSJywbmxi95fxQm3coXBFwognjFLla9X6tr8BdNyaIKNOEkaRbRcm0/zYAqN19N1oyhg== + reserved-words@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/reserved-words/-/reserved-words-0.1.2.tgz#00a0940f98cd501aeaaac316411d9adc52b31ab1" @@ -7693,7 +8029,7 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rxjs@^6.6.0: +rxjs@^6.6.0, rxjs@^6.6.3: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" integrity sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ== @@ -7868,6 +8204,11 @@ server-destroy@^1.0.1: resolved "https://registry.yarnpkg.com/server-destroy/-/server-destroy-1.0.1.tgz#f13bf928e42b9c3e79383e61cc3998b5d14e6cdd" integrity sha1-8Tv5KOQrnD55OD5hzDmYtdFObN0= +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + set-value@^2.0.0, set-value@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" @@ -7922,7 +8263,7 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.2, signal-exit@^3.0.3: +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== @@ -8050,6 +8391,11 @@ source-map@^0.7.3, source-map@~0.7.2: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383" integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ== +spawn-command@^0.0.2-1: + version "0.0.2-1" + resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2-1.tgz#62f5e9466981c1b796dc5929937e11c9c6921bd0" + integrity sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A= + spdx-correct@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" @@ -8142,6 +8488,11 @@ std-env@^2.2.1, std-env@^2.3.0: dependencies: ci-info "^3.0.0" +steno@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/steno/-/steno-1.0.0.tgz#475e32c6066ec9760229eaaf1550601764fbecba" + integrity sha512-C/KgCvEa1yWnpHmaPjAXrz1yWxh6hs+HvhqqPa71euaQmNi1wr4+WFo57VQxjKKuFl2KqS7gtlrN0oxj2noQLw== + stream-browserify@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" @@ -8184,7 +8535,16 @@ strict-uri-encode@^2.0.0: resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" integrity sha1-ucczDHBChi9rFC3CdLvMWGbONUY= -string-width@^2.0.0: +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -8240,7 +8600,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^3.0.0: +strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= @@ -8327,6 +8687,13 @@ supports-color@^7.0.0, supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +supports-color@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + svg-tags@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" @@ -8379,7 +8746,7 @@ tar-stream@^2.2.0: inherits "^2.0.3" readable-stream "^3.1.1" -tar@^6.0.2: +tar@^6.0.2, tar@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== @@ -8544,6 +8911,11 @@ totalist@^1.0.0: resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== +tree-kill@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" + integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== + ts-pnp@^1.1.6: version "1.2.0" resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" @@ -8603,7 +8975,7 @@ type-fest@^0.6.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== -type-fest@^0.8.1: +type-fest@^0.8.0, type-fest@^0.8.1: version "0.8.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== @@ -9103,6 +9475,13 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + widest-line@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" @@ -9188,6 +9567,11 @@ y18n@^4.0.0: resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" @@ -9203,6 +9587,24 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yargs-parser@^20.2.2: + version "20.2.7" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a" + integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw== + +yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"