From 60d73beb75e40990d3f0c69f75ec31fa70a1c72b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Wi=C5=9Bniewski?= Date: Thu, 31 Dec 2020 11:38:23 +0100 Subject: [PATCH 01/10] Code review --- .env-sample | 7 +- .../20201230195946_auth/migration.sql | 61 ++++ api-helpers/prisma/schema.prisma | 47 ++- .../LoadingScreen/LoadingScreen.module.css | 8 + components/LoadingScreen/LoadingScreen.tsx | 9 + package.json | 2 + pages/_app.tsx | 5 +- pages/admin.tsx | 32 ++ pages/api/auth/[...nextauth].ts | 58 ++++ yarn.lock | 292 +++++++++++++++++- 10 files changed, 494 insertions(+), 27 deletions(-) create mode 100644 api-helpers/prisma/migrations/20201230195946_auth/migration.sql create mode 100644 components/LoadingScreen/LoadingScreen.module.css create mode 100644 components/LoadingScreen/LoadingScreen.tsx create mode 100644 pages/admin.tsx create mode 100644 pages/api/auth/[...nextauth].ts diff --git a/.env-sample b/.env-sample index f77f131f..0c6d8ece 100644 --- a/.env-sample +++ b/.env-sample @@ -3,7 +3,6 @@ DATABASE_URL="postgresql://postgres:polskifrontend@localhost:5432/polskifrontend FEED_UPDATE_SECRET="supertajne" CURSOR_ENCRYPTION_KEY="d6F3Efeqd6F3Efeq" - CAPTCHA_SECRET_KEY=0x0000000000000000000000000000000000000000 MAILGUN_DOMAIN="domena1337.mailgun.org" @@ -14,3 +13,9 @@ NEXT_PUBLIC_GA_TRACKING_ID="" NEXT_PUBLIC_SENTRY_DSN="" NEXT_PUBLIC_CAPTCHA_SITE_KEY=10000000-ffff-ffff-ffff-000000000001 NEXT_PUBLIC_URL="localhost:3000" + +GITHUB_ID="supertajne" +GITHUB_SECRET="bardzotajne" +SECRET="anothersecret" +JWT_SECRET="hmmmmmm" +NEXTAUTH_URL="localhost:3000" diff --git a/api-helpers/prisma/migrations/20201230195946_auth/migration.sql b/api-helpers/prisma/migrations/20201230195946_auth/migration.sql new file mode 100644 index 00000000..09ac0118 --- /dev/null +++ b/api-helpers/prisma/migrations/20201230195946_auth/migration.sql @@ -0,0 +1,61 @@ +/* + Warnings: + + - You are about to drop the `Session` table. If the table is not empty, all the data it contains will be lost. + - You are about to drop the `User` table. If the table is not empty, all the data it contains will be lost. + +*/ +-- DropForeignKey +ALTER TABLE "Session" DROP CONSTRAINT "Session_userId_fkey"; + +-- CreateTable +CREATE TABLE "accounts" ( +"id" SERIAL, + "compound_id" TEXT NOT NULL, + "user_id" INTEGER NOT NULL, + "provider_type" TEXT NOT NULL, + "provider_id" TEXT NOT NULL, + "provider_account_id" TEXT NOT NULL, + "refresh_token" TEXT, + "access_token" TEXT, + "access_token_expires" TIMESTAMP(3), + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "users" ( +"id" SERIAL, + "name" TEXT, + "email" TEXT, + "email_verified" TIMESTAMP(3), + "image" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "role" "UserRole" NOT NULL DEFAULT E'USER', + + PRIMARY KEY ("id") +); + +-- DropTable +DROP TABLE "Session"; + +-- DropTable +DROP TABLE "User"; + +-- CreateIndex +CREATE UNIQUE INDEX "accounts.compound_id_unique" ON "accounts"("compound_id"); + +-- CreateIndex +CREATE INDEX "providerAccountId" ON "accounts"("provider_account_id"); + +-- CreateIndex +CREATE INDEX "providerId" ON "accounts"("provider_id"); + +-- CreateIndex +CREATE INDEX "userId" ON "accounts"("user_id"); + +-- CreateIndex +CREATE UNIQUE INDEX "users.email_unique" ON "users"("email"); diff --git a/api-helpers/prisma/schema.prisma b/api-helpers/prisma/schema.prisma index 5acda840..0a9b0a41 100644 --- a/api-helpers/prisma/schema.prisma +++ b/api-helpers/prisma/schema.prisma @@ -8,27 +8,40 @@ datasource db { url = env("DATABASE_URL") } -model User { - id String @default(cuid()) @id - name String? - email String @unique - password String - - role UserRole @default(USER) - - createdAt DateTime @default(now()) - updatedAt DateTime @default(now()) @updatedAt +model Account { + id Int @default(autoincrement()) @id + compoundId String @unique @map(name: "compound_id") + userId Int @map(name: "user_id") + providerType String @map(name: "provider_type") + providerId String @map(name: "provider_id") + providerAccountId String @map(name: "provider_account_id") + refreshToken String? @map(name: "refresh_token") + accessToken String? @map(name: "access_token") + accessTokenExpires DateTime? @map(name: "access_token_expires") + createdAt DateTime @default(now()) @map(name: "created_at") + updatedAt DateTime @default(now()) @map(name: "updated_at") + + @@index([providerAccountId], name: "providerAccountId") + @@index([providerId], name: "providerId") + @@index([userId], name: "userId") + + @@map(name: "accounts") } -model Session { - id String @id - validUntil DateTime - userId String - user User @relation(fields: [userId], references: [id]) - createdAt DateTime @default(now()) - updatedAt DateTime @default(now()) @updatedAt +model User { + id Int @default(autoincrement()) @id + name String? + email String? @unique + emailVerified DateTime? @map(name: "email_verified") + image String? + createdAt DateTime @default(now()) @map(name: "created_at") + updatedAt DateTime @default(now()) @map(name: "updated_at") + + role UserRole @default(USER) + + @@map(name: "users") } enum UserRole { diff --git a/components/LoadingScreen/LoadingScreen.module.css b/components/LoadingScreen/LoadingScreen.module.css new file mode 100644 index 00000000..e910a04c --- /dev/null +++ b/components/LoadingScreen/LoadingScreen.module.css @@ -0,0 +1,8 @@ +.loadingScreen { + display: flex; + justify-content: center; + align-items: center; + position: absolute; + inset: 0; + background-color: var(--white); +} diff --git a/components/LoadingScreen/LoadingScreen.tsx b/components/LoadingScreen/LoadingScreen.tsx new file mode 100644 index 00000000..082a578f --- /dev/null +++ b/components/LoadingScreen/LoadingScreen.tsx @@ -0,0 +1,9 @@ +import styles from './LoadingScreen.module.css'; + +export const LoadingScreen = () => { + return ( +
+ Ładowanie... +
+ ); +}; diff --git a/package.json b/package.json index d1fca97d..a17e1884 100644 --- a/package.json +++ b/package.json @@ -52,6 +52,7 @@ "mailgun-js": "0.22.0", "ms": "2.1.3", "next": "10.0.4", + "next-auth": "3.1.0", "next-images": "1.6.2", "next-seo": "4.17.0", "normalize.css": "8.0.1", @@ -82,6 +83,7 @@ "@types/mailgun-js": "0.22.11", "@types/mongodb": "3.6.3", "@types/ms": "0.7.31", + "@types/next-auth": "3.1.19", "@types/node": "14.14.16", "@types/pino": "6.3.4", "@types/react": "17.0.0", diff --git a/pages/_app.tsx b/pages/_app.tsx index 24b55da5..57798a1e 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,6 +1,7 @@ import 'normalize.css/normalize.css'; import '../global.scss'; import '../icomoon-v1.0/style.css'; +import { Provider } from 'next-auth/client'; import { DefaultSeo } from 'next-seo'; import type { AppProps } from 'next/app'; import Head from 'next/head'; @@ -77,7 +78,9 @@ export default function MyApp({ - + + + ); } diff --git a/pages/admin.tsx b/pages/admin.tsx new file mode 100644 index 00000000..c62f08bb --- /dev/null +++ b/pages/admin.tsx @@ -0,0 +1,32 @@ +import { signIn, signOut, useSession } from 'next-auth/client'; + +import { Layout } from '../components/Layout'; +import { LoadingScreen } from '../components/LoadingScreen/LoadingScreen'; + +export default function AdminPage() { + const [session, isLoading] = useSession(); + + if (isLoading) { + return ( + + + + ); + } + + if (session) { + return ( + +
Logged in
+ +
+ ); + } + + return ( + +
You are not logged
+ +
+ ); +} diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts new file mode 100644 index 00000000..dd37f4b8 --- /dev/null +++ b/pages/api/auth/[...nextauth].ts @@ -0,0 +1,58 @@ +import Boom from '@hapi/boom'; +import type { NextApiHandler } from 'next'; +import type { InitOptions } from 'next-auth'; +import NextAuth from 'next-auth'; +import Adapters from 'next-auth/adapters'; +import Providers from 'next-auth/providers'; + +import { closeConnection, openConnection } from '../../../api-helpers/db'; + +const authHandler: NextApiHandler = async (req, res) => { + const prisma = await openConnection(); + const options: InitOptions = { + providers: [ + Providers.GitHub({ + clientId: process.env.GITHUB_ID as string, + clientSecret: process.env.GITHUB_SECRET as string, + }), + ], + secret: process.env.SECRET, + adapter: Adapters.Prisma.Adapter({ + prisma, + }), + session: { + jwt: true, + maxAge: 24 * 60 * 60, // 1 day + }, + jwt: { + secret: process.env.JWT_SECRET, + }, + callbacks: { + session: async (session) => { + try { + const prisma = await openConnection(); + const account = await prisma.account.findFirst({ + where: { + accessToken: session.accessToken, + }, + }); + const user = await prisma.user.findUnique({ + where: { + id: account?.userId, + }, + }); + session.user.role = user?.role; + return Promise.resolve(session); + } catch (err) { + throw Boom.unauthorized(); + } finally { + await closeConnection(); + } + }, + }, + }; + + return NextAuth(req, res, options); +}; + +export default authHandler; diff --git a/yarn.lock b/yarn.lock index d16a75e3..315ecab9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1395,6 +1395,11 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.14.0.tgz#c67fc20a4d891447ca1a855d7d70fa79a3533001" integrity sha512-sDOAZcYwynHFTbLo6n8kIbLiVF3a3BLkrmehJUyEbT9F+Smbi47kLGS2gG2g0fjBLR/Lr1InPD7kXL7FaTqEkw== +"@panva/asn1.js@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@panva/asn1.js/-/asn1.js-1.0.0.tgz#dd55ae7b8129e02049f009408b97c61ccf9032f6" + integrity sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw== + "@polka/url@^1.0.0-next.9": version "1.0.0-next.11" resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.11.tgz#aeb16f50649a91af79dbe36574b66d0f9e4d9f71" @@ -1577,6 +1582,11 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@sqltools/formatter@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.2.tgz#9390a8127c0dcba61ebd7fdcc748655e191bdd68" + integrity sha512-/5O7Fq6Vnv8L6ucmPjaWbVG1XkP4FO+w5glqfkIsq3Xw4oyNAdJddbnYodNDAfjVUvo/rrSCTom4kAND7T1o5Q== + "@swc-node/core@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@swc-node/core/-/core-1.1.1.tgz#639921cfc97ee84b1e3bf625518c693b6a5a1344" @@ -1829,6 +1839,16 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== +"@types/next-auth@3.1.19": + version "3.1.19" + resolved "https://registry.yarnpkg.com/@types/next-auth/-/next-auth-3.1.19.tgz#3744eb765aa7d62b868f44d78891ba9db39c6a93" + integrity sha512-ilWteGkZ1P+xfm2kwJbP9T8mPwNi3oGT4IADeZwf4888ZpM0WrQNSwWC5SLadqT5iEtwM1DG5TB8QzbBFxjTSg== + dependencies: + "@types/node" "*" + "@types/react" "*" + jose "^1.28.0" + typeorm "^0.2.24" + "@types/node@*", "@types/node@14.14.16": version "14.14.16" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.16.tgz#3cc351f8d48101deadfed4c9e4f116048d437b4b" @@ -2436,6 +2456,11 @@ ansicolors@~0.3.2: resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" integrity sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk= +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -2459,6 +2484,11 @@ app-path@^3.2.0: dependencies: execa "^1.0.0" +app-root-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad" + integrity sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw== + aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -3057,6 +3087,11 @@ buffer-alloc@^1.2.0: buffer-alloc-unsafe "^1.1.0" buffer-fill "^1.0.0" +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-fill@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" @@ -3434,6 +3469,18 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" +cli-highlight@^2.1.4: + version "2.1.9" + resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.9.tgz#4f4ecb05326d70d56d4b4249fabf9a70fb002497" + integrity sha512-t8RNIZgiI24i/mslZ8XT8o660RUj5ZbUJpEZrZa/BNekTzdC2LfMRAnt0Y7sgzNM4FGW5tmWg/YnbTH8o1eIOQ== + dependencies: + chalk "^4.0.0" + highlight.js "^10.0.0" + mz "^2.4.0" + parse5 "^5.1.1" + parse5-htmlparser2-tree-adapter "^6.0.0" + yargs "^15.0.0" + cli-progress@^3.4.0: version "3.8.2" resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.8.2.tgz#abaf1fc6d6401351f16f068117a410554a0eb8c7" @@ -3894,6 +3941,11 @@ crypto-browserify@3.12.0, crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" +crypto-js@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.0.0.tgz#2904ab2677a9d042856a2ea2ef80de92e4a36dcc" + integrity sha512-bzHZN8Pn+gS7DQA6n+iUmBfl0hO5DJq++QP3U6uTucDtk/0iGpXd/Gg7CGR0p8tJhofJyaKoWBuJI4eAO00BBg== + css-blank-pseudo@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" @@ -4443,6 +4495,13 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.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" + edit-string@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/edit-string/-/edit-string-1.1.6.tgz#1c9a889dbc7e600767f4feca69d08a7ce15962f4" @@ -5176,6 +5235,11 @@ figgy-pudding@^3.5.1: resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== +figlet@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.5.0.tgz#2db4d00a584e5155a96080632db919213c3e003c" + integrity sha512-ZQJM4aifMpz6H19AW1VqvZ7l4pOE9p7i/3LyxgO2kp+PO/VcDYNqIHEMtkccqIhTXMKci4kjueJr/iCQEaT/Ww== + figures@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" @@ -5447,6 +5511,11 @@ 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= +futoin-hkdf@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/futoin-hkdf/-/futoin-hkdf-1.3.2.tgz#cd9a09153e3db7d166b9717f872991a4950430cd" + integrity sha512-3EVi3ETTyJg5PSXlxLCaUVVn0pSbDf62L3Gwxne7Uq+d8adOSNWQAad4gg7WToHkcgnCJb3Wlb1P8r4Evj4GPw== + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -5911,6 +5980,11 @@ heroku@7.47.6: tslib "1.9.3" uuid "3.3.2" +highlight.js@^10.0.0: + version "10.5.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.5.0.tgz#3f09fede6a865757378f2d9ebdcbc15ba268f98f" + integrity sha512-xTmvd9HiIHR6L53TMC7TKolEj65zG1XU+Onr8oi86mYa+nLcIbxTTWkpW7CsEwv/vK7u1zb8alZIMLDqqN6KTw== + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -7165,6 +7239,13 @@ joi@^17.3.0: "@sideway/formula" "^3.0.0" "@sideway/pinpoint" "^2.0.0" +jose@^1.27.2, jose@^1.28.0: + version "1.28.0" + resolved "https://registry.yarnpkg.com/jose/-/jose-1.28.0.tgz#0803f8c71f43cd293a9d931c555c30531f5ca5dc" + integrity sha512-JmfDRzt/HSj8ipd9TsDtEHoLUnLYavG+7e8F6s1mx2jfVSfXOTaFQsJUydbjJpTnTDHP1+yKL9Ke7ktS/a0Eiw== + dependencies: + "@panva/asn1.js" "^1.0.0" + joycon@^2.2.5: version "2.2.5" resolved "https://registry.yarnpkg.com/joycon/-/joycon-2.2.5.tgz#8d4cf4cbb2544d7b7583c216fcdfec19f6be1615" @@ -7175,7 +7256,7 @@ joycon@^2.2.5: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.12.1, js-yaml@^3.13.1: +js-yaml@^3.12.1, js-yaml@^3.13.1, js-yaml@^3.14.0: version "3.14.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== @@ -7300,6 +7381,22 @@ jsonfile@^4.0.0: optionalDependencies: graceful-fs "^4.1.6" +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" + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -7318,6 +7415,28 @@ jsprim@^1.2.2: array-includes "^3.1.2" object.assign "^4.1.2" +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@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-2.2.0.tgz#7d86bd56679f58ce6a84704a657dd392bba81a79" + integrity sha1-fYa9VmefWM5qhHBKZX3TkruoGnk= + keypair@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/keypair/-/keypair-1.0.1.tgz#7603719270afb6564ed38a22087a06fc9aa4ea1b" @@ -7613,11 +7732,46 @@ lodash.has@^4.5.2: resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862" integrity sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI= +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.keyby@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.keyby/-/lodash.keyby-4.6.0.tgz#7f6a1abda93fd24e22728a4d361ed8bcba5a4354" integrity sha1-f2oavak/0k4icopNNh7YvLpaQ1Q= +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.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -7957,7 +8111,7 @@ mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5: dependencies: minimist "^1.2.5" -mkdirp@~1.0.4: +mkdirp@^1.0.4, mkdirp@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -8045,6 +8199,15 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== +mz@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + nan@^2.12.1: version "2.14.2" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19" @@ -8122,6 +8285,24 @@ netrc-parser@3.1.6, netrc-parser@^3.1.4, netrc-parser@^3.1.6: debug "^3.1.0" execa "^0.10.0" +next-auth@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-3.1.0.tgz#45ebf94fc481be1413d36ec72522add2a6739585" + integrity sha512-e+s6hjPZpqbnjla9WOi0VuLkDlLMU3cJmS0jTBBvsvSGsOPvMbaCCAMBEoNV3nWSgPrq6zLG2dixmCCxzG7fXA== + dependencies: + crypto-js "^4.0.0" + futoin-hkdf "^1.3.2" + jose "^1.27.2" + jsonwebtoken "^8.5.1" + jwt-decode "^2.2.0" + nodemailer "^6.4.6" + oauth "^0.9.15" + preact "^10.4.1" + preact-render-to-string "^5.1.7" + querystring "^0.2.0" + require_optional "^1.0.1" + typeorm "^0.2.24" + next-images@1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/next-images/-/next-images-1.6.2.tgz#e5535ba468c3c857025e7fa07a27c773326223ad" @@ -8309,6 +8490,11 @@ node-request-interceptor@^0.5.3: debug "^4.3.0" headers-utils "^1.2.0" +nodemailer@^6.4.6: + version "6.4.17" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.4.17.tgz#8de98618028953b80680775770f937243a7d7877" + integrity sha512-89ps+SBGpo0D4Bi5ZrxcrCiRFaMmkCt+gItMXQGzEtZVR3uAD3QAQIDoxTWnx3ky0Dwwy/dhFrQ+6NNGXpw/qQ== + noop-logger@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" @@ -8431,6 +8617,11 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== +oauth@^0.9.15: + version "0.9.15" + resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" + integrity sha1-vR/vr2hslrdUda7VGWQS/2DPucE= + object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -8750,6 +8941,11 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parent-require@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parent-require/-/parent-require-1.0.0.tgz#746a167638083a860b0eef6732cb27ed46c32977" + integrity sha1-dGoWdjgIOoYLDu9nMssn7UbDKXc= + parse-asn1@^5.0.0, parse-asn1@^5.1.5: version "5.1.6" resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" @@ -8793,7 +8989,7 @@ parse5-htmlparser2-tree-adapter@^6.0.0: dependencies: parse5 "^6.0.1" -parse5@5.1.1: +parse5@5.1.1, parse5@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== @@ -9457,6 +9653,18 @@ postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0. source-map "^0.6.1" supports-color "^6.1.0" +preact-render-to-string@^5.1.7: + version "5.1.12" + resolved "https://registry.yarnpkg.com/preact-render-to-string/-/preact-render-to-string-5.1.12.tgz#3d258a177ef8947f768dd0f2c56629e7fda2dc39" + integrity sha512-nXVCOpvepSk9AfPwqS08rf9NDOCs8eeYYlG+7tE85iP5jVyjz+aYb1BYaP5SPdfVWVrzI9L5NzxozUvKaD96tA== + dependencies: + pretty-format "^3.8.0" + +preact@^10.4.1: + version "10.5.8" + resolved "https://registry.yarnpkg.com/preact/-/preact-10.5.8.tgz#96e71e2caadf60b5ff901f0e4772a46ba0756336" + integrity sha512-8d0FfBX3O0ay34i15mTckXicSsvaQLemPUByXTyfQUxDeFqZhbtnftVZMNqX3zEJLHcy1bqRu9t+V4GqJtG1TQ== + prebuild-install@^5.3.5: version "5.3.6" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-5.3.6.tgz#7c225568d864c71d89d07f8796042733a3f54291" @@ -9526,6 +9734,11 @@ pretty-format@^26.0.0, pretty-format@^26.6.2: ansi-styles "^4.0.0" react-is "^17.0.1" +pretty-format@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385" + integrity sha1-v77VbV6ad2ZF9LH/eqGjrE+jw4U= + printf@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/printf/-/printf-0.3.0.tgz#6918ca5237c047e19cf004b69e6bcfafbef1ce82" @@ -9900,6 +10113,11 @@ redis-parser@^3.0.0: dependencies: redis-errors "^1.0.0" +reflect-metadata@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + regenerator-runtime@^0.13.4: version "0.13.7" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" @@ -10243,7 +10461,7 @@ sass@1.30.0, sass@^1.26.5: dependencies: chokidar ">=2.0.0 <4.0.0" -sax@^1.2.4, sax@~1.2.4: +sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== @@ -10354,7 +10572,7 @@ setprototypeof@1.1.1: resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== -sha.js@^2.4.0, sha.js@^2.4.8: +sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8: version "2.4.11" resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== @@ -11287,6 +11505,20 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + throat@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/throat/-/throat-5.0.0.tgz#c5199235803aad18754a667d659b5e72ce16764b" @@ -11500,7 +11732,7 @@ tslib@1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" integrity sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ== -tslib@^1, tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: +tslib@^1, tslib@^1.10.0, tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== @@ -11614,6 +11846,28 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typeorm@^0.2.24: + version "0.2.29" + resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.29.tgz#401289dc91900d72eccb26e31cdb7f0591a2272e" + integrity sha512-ih1vrTe3gEAGKRcWlcsTRxTL7gNjacQE498wVGuJ3ZRujtMqPZlbAWuC7xDzWCRjQnkZYNwZQeG9UgKfxSHB5g== + dependencies: + "@sqltools/formatter" "1.2.2" + app-root-path "^3.0.0" + buffer "^5.5.0" + chalk "^4.1.0" + cli-highlight "^2.1.4" + debug "^4.1.1" + dotenv "^8.2.0" + glob "^7.1.6" + js-yaml "^3.14.0" + mkdirp "^1.0.4" + reflect-metadata "^0.1.13" + sha.js "^2.4.11" + tslib "^1.13.0" + xml2js "^0.4.23" + yargonaut "^1.1.2" + yargs "^16.0.3" + typescript-plugin-css-modules@3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/typescript-plugin-css-modules/-/typescript-plugin-css-modules-3.0.1.tgz#6d9a9e11660fcba60b5679797bdcf61621705062" @@ -12143,11 +12397,24 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== +xml2js@^0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + xmlbuilder@^9.0.7: version "9.0.7" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" @@ -12201,6 +12468,15 @@ yaml@^1.10.0: resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e" integrity sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg== +yargonaut@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/yargonaut/-/yargonaut-1.1.4.tgz#c64f56432c7465271221f53f5cc517890c3d6e0c" + integrity sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA== + dependencies: + chalk "^1.1.1" + figlet "^1.1.1" + parent-require "^1.0.0" + yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" @@ -12238,7 +12514,7 @@ yargs@^13.3.0: y18n "^4.0.0" yargs-parser "^13.1.2" -yargs@^15.0.1, yargs@^15.4.1: +yargs@^15.0.0, yargs@^15.0.1, yargs@^15.4.1: version "15.4.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== @@ -12255,7 +12531,7 @@ yargs@^15.0.1, yargs@^15.4.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^16.2.0: +yargs@^16.0.3, 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== From addcea6361feb9ad4537102c08f937d595dd2fd7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Wi=C5=9Bniewski?= Date: Thu, 31 Dec 2020 20:11:49 +0100 Subject: [PATCH 02/10] Code review --- components/AdminPanel/AdminPanel.module.css | 19 ++++++++++++ components/AdminPanel/AdminPanel.tsx | 34 +++++++++++++++++++++ next-env.d.ts | 12 ++++++++ pages/admin.tsx | 26 ++-------------- pages/api/auth/[...nextauth].ts | 31 +++++++++++++------ 5 files changed, 88 insertions(+), 34 deletions(-) create mode 100644 components/AdminPanel/AdminPanel.module.css create mode 100644 components/AdminPanel/AdminPanel.tsx diff --git a/components/AdminPanel/AdminPanel.module.css b/components/AdminPanel/AdminPanel.module.css new file mode 100644 index 00000000..5fceb715 --- /dev/null +++ b/components/AdminPanel/AdminPanel.module.css @@ -0,0 +1,19 @@ +.section { + max-width: 73rem; + margin: 0 auto; +} + +.heading { + padding: 2rem 0 1rem; + border-bottom: 2px solid var(--gray-border); + text-align: center; + text-transform: uppercase; + color: var(--gray-text); + font-size: 1.25rem; +} + +.p { + text-align: center; + color: var(--gray-text); + font-size: 1.25rem; +} diff --git a/components/AdminPanel/AdminPanel.tsx b/components/AdminPanel/AdminPanel.tsx new file mode 100644 index 00000000..56cf2ad0 --- /dev/null +++ b/components/AdminPanel/AdminPanel.tsx @@ -0,0 +1,34 @@ +import { signIn, useSession } from 'next-auth/client'; +import { useEffect } from 'react'; + +import { LoadingScreen } from '../LoadingScreen/LoadingScreen'; + +import styles from './AdminPanel.module.css'; + +export const AdminPanel = () => { + const [session, isLoading] = useSession(); + + useEffect(() => { + if (!isLoading && !session) { + void signIn(); + } + }, [session, isLoading]); + + if (isLoading) { + return ; + } + + if (session?.role === 'ADMIN') { +
; // @to-do admin-panel + } + + return ( +
+

Brak uprawnień

+

+ Nie masz odpowiednich uprawnień, żeby korzystać z tej podstrony, w celu weryfikacji + skontaktuj się z administracją serwisu. +

+
+ ); +}; diff --git a/next-env.d.ts b/next-env.d.ts index ef21bf91..c59f882b 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -3,9 +3,21 @@ /// import 'jest-extended'; +import { useSession } from 'next-auth/client'; declare namespace NodeJS { interface ProcessEnv { readonly NEXT_PUBLIC_URL: string; } } + +type Role = 'USER' | 'ADMIN'; + +declare module 'next-auth' { + interface User { + readonly userId?: number; + readonly role?: Role; + } + + declare function useSession(): readonly [Session | null | undefined, boolean]; +} diff --git a/pages/admin.tsx b/pages/admin.tsx index c62f08bb..ba92e6eb 100644 --- a/pages/admin.tsx +++ b/pages/admin.tsx @@ -1,32 +1,10 @@ -import { signIn, signOut, useSession } from 'next-auth/client'; - +import { AdminPanel } from '../components/AdminPanel/AdminPanel'; import { Layout } from '../components/Layout'; -import { LoadingScreen } from '../components/LoadingScreen/LoadingScreen'; export default function AdminPage() { - const [session, isLoading] = useSession(); - - if (isLoading) { - return ( - - - - ); - } - - if (session) { - return ( - -
Logged in
- -
- ); - } - return ( -
You are not logged
- +
); } diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index dd37f4b8..061d73ae 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -28,27 +28,38 @@ const authHandler: NextApiHandler = async (req, res) => { secret: process.env.JWT_SECRET, }, callbacks: { - session: async (session) => { + jwt: async (token, user?) => { + if (!user) { + // If it's not sign in operation return already created token + return Promise.resolve(token); + } + + const userId = user.userId; try { - const prisma = await openConnection(); - const account = await prisma.account.findFirst({ - where: { - accessToken: session.accessToken, - }, - }); const user = await prisma.user.findUnique({ where: { - id: account?.userId, + id: userId, }, }); - session.user.role = user?.role; - return Promise.resolve(session); + token.userId = userId; + token.role = user?.role; + return Promise.resolve(token); } catch (err) { throw Boom.unauthorized(); } finally { await closeConnection(); } }, + session: (session, token) => { + return Promise.resolve({ + ...session, + user: { + ...session.user, + role: token.role, + userId: token.userId, + }, + }); + }, }, }; From 667321f30ac9fb5d8dd0367745a9b6d9b95461a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Wi=C5=9Bniewski?= Date: Thu, 31 Dec 2020 20:21:45 +0100 Subject: [PATCH 03/10] Fix admin panel --- components/AdminPanel/AdminPanel.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/AdminPanel/AdminPanel.tsx b/components/AdminPanel/AdminPanel.tsx index 56cf2ad0..b0caf2e2 100644 --- a/components/AdminPanel/AdminPanel.tsx +++ b/components/AdminPanel/AdminPanel.tsx @@ -8,6 +8,8 @@ import styles from './AdminPanel.module.css'; export const AdminPanel = () => { const [session, isLoading] = useSession(); + console.log(session); + useEffect(() => { if (!isLoading && !session) { void signIn(); @@ -18,8 +20,8 @@ export const AdminPanel = () => { return ; } - if (session?.role === 'ADMIN') { -
; // @to-do admin-panel + if (session?.user.role === 'ADMIN') { + return
; // @to-do admin-panel } return ( From 4a987b07313620c551728153db9db153b9727261 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Wi=C5=9Bniewski?= Date: Thu, 31 Dec 2020 20:26:45 +0100 Subject: [PATCH 04/10] Delete unused code --- components/AdminPanel/AdminPanel.tsx | 2 -- next-env.d.ts | 3 --- 2 files changed, 5 deletions(-) diff --git a/components/AdminPanel/AdminPanel.tsx b/components/AdminPanel/AdminPanel.tsx index b0caf2e2..c9ace852 100644 --- a/components/AdminPanel/AdminPanel.tsx +++ b/components/AdminPanel/AdminPanel.tsx @@ -8,8 +8,6 @@ import styles from './AdminPanel.module.css'; export const AdminPanel = () => { const [session, isLoading] = useSession(); - console.log(session); - useEffect(() => { if (!isLoading && !session) { void signIn(); diff --git a/next-env.d.ts b/next-env.d.ts index c59f882b..8d391a0e 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -3,7 +3,6 @@ /// import 'jest-extended'; -import { useSession } from 'next-auth/client'; declare namespace NodeJS { interface ProcessEnv { @@ -18,6 +17,4 @@ declare module 'next-auth' { readonly userId?: number; readonly role?: Role; } - - declare function useSession(): readonly [Session | null | undefined, boolean]; } From 81c9733b8e379726d861c3e3d9d8c1041b913711 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Wi=C5=9Bniewski?= Date: Thu, 31 Dec 2020 22:09:22 +0100 Subject: [PATCH 05/10] Code review --- .env-sample | 2 +- api-helpers/mailFunctions.ts | 7 +++++-- components/AdminPanel/AdminPanel.tsx | 7 +++++-- pages/admin.tsx | 6 +++++- pages/api/auth/[...nextauth].ts | 1 + 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.env-sample b/.env-sample index 0c6d8ece..cd0f205b 100644 --- a/.env-sample +++ b/.env-sample @@ -18,4 +18,4 @@ GITHUB_ID="supertajne" GITHUB_SECRET="bardzotajne" SECRET="anothersecret" JWT_SECRET="hmmmmmm" -NEXTAUTH_URL="localhost:3000" +NEXTAUTH_URL="http://localhost:3000" diff --git a/api-helpers/mailFunctions.ts b/api-helpers/mailFunctions.ts index 0f6f5497..1c589950 100644 --- a/api-helpers/mailFunctions.ts +++ b/api-helpers/mailFunctions.ts @@ -42,14 +42,17 @@ export const sendNewCreatorNotification = async ({ name, href, rss, creatorEmail try { const prisma = await openConnection(); - const admins = await prisma.user.findMany({ + const admins = (await prisma.user.findMany({ where: { role: UserRole.ADMIN, + email: { + not: null, + }, }, select: { email: true, }, - }); + })) as ReadonlyArray<{ readonly email: string }>; await sendEmail( admins.map((a) => a.email), diff --git a/components/AdminPanel/AdminPanel.tsx b/components/AdminPanel/AdminPanel.tsx index c9ace852..1e859805 100644 --- a/components/AdminPanel/AdminPanel.tsx +++ b/components/AdminPanel/AdminPanel.tsx @@ -5,7 +5,7 @@ import { LoadingScreen } from '../LoadingScreen/LoadingScreen'; import styles from './AdminPanel.module.css'; -export const AdminPanel = () => { +const AdminPanel = () => { const [session, isLoading] = useSession(); useEffect(() => { @@ -26,9 +26,12 @@ export const AdminPanel = () => {

Brak uprawnień

- Nie masz odpowiednich uprawnień, żeby korzystać z tej podstrony, w celu weryfikacji + Nie masz odpowiednich uprawnień, żeby korzystać z tej podstrony. W celu weryfikacji skontaktuj się z administracją serwisu.

); }; + +// eslint-disable-next-line import/no-default-export +export default AdminPanel; diff --git a/pages/admin.tsx b/pages/admin.tsx index ba92e6eb..a3770351 100644 --- a/pages/admin.tsx +++ b/pages/admin.tsx @@ -1,6 +1,10 @@ -import { AdminPanel } from '../components/AdminPanel/AdminPanel'; +import dynamic from 'next/dynamic'; + import { Layout } from '../components/Layout'; +// eslint-disable-next-line import/dynamic-import-chunkname +const AdminPanel = dynamic(() => import('../components/AdminPanel/AdminPanel')); + export default function AdminPage() { return ( diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index 061d73ae..32340751 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -40,6 +40,7 @@ const authHandler: NextApiHandler = async (req, res) => { where: { id: userId, }, + select: { role: true }, }); token.userId = userId; token.role = user?.role; From edfb75a124a5f38302bc815a80ee3c86b4b55773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Wi=C5=9Bniewski?= Date: Thu, 31 Dec 2020 22:25:11 +0100 Subject: [PATCH 06/10] Code review --- components/AdminPanel/AdminPanel.tsx | 5 +---- pages/admin.tsx | 5 +++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/components/AdminPanel/AdminPanel.tsx b/components/AdminPanel/AdminPanel.tsx index 1e859805..5561cfb3 100644 --- a/components/AdminPanel/AdminPanel.tsx +++ b/components/AdminPanel/AdminPanel.tsx @@ -5,7 +5,7 @@ import { LoadingScreen } from '../LoadingScreen/LoadingScreen'; import styles from './AdminPanel.module.css'; -const AdminPanel = () => { +export const AdminPanel: React.VFC = () => { const [session, isLoading] = useSession(); useEffect(() => { @@ -32,6 +32,3 @@ const AdminPanel = () => { ); }; - -// eslint-disable-next-line import/no-default-export -export default AdminPanel; diff --git a/pages/admin.tsx b/pages/admin.tsx index a3770351..75b6253b 100644 --- a/pages/admin.tsx +++ b/pages/admin.tsx @@ -2,8 +2,9 @@ import dynamic from 'next/dynamic'; import { Layout } from '../components/Layout'; -// eslint-disable-next-line import/dynamic-import-chunkname -const AdminPanel = dynamic(() => import('../components/AdminPanel/AdminPanel')); +const AdminPanel = dynamic(() => + import('../components/AdminPanel/AdminPanel').then(({ AdminPanel }) => ({ default: AdminPanel })), +); export default function AdminPage() { return ( From f4d8a2fc47cab814713fe4e0e1b5bd2bd1ddd1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Wi=C5=9Bniewski?= Date: Fri, 1 Jan 2021 16:57:14 +0100 Subject: [PATCH 07/10] Fix dynamic import issue --- components/AdminPanel/AdminPanel.tsx | 2 +- pages/admin.tsx | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/components/AdminPanel/AdminPanel.tsx b/components/AdminPanel/AdminPanel.tsx index 5561cfb3..9ada4a08 100644 --- a/components/AdminPanel/AdminPanel.tsx +++ b/components/AdminPanel/AdminPanel.tsx @@ -5,7 +5,7 @@ import { LoadingScreen } from '../LoadingScreen/LoadingScreen'; import styles from './AdminPanel.module.css'; -export const AdminPanel: React.VFC = () => { +export const AdminPanel: React.FC = () => { const [session, isLoading] = useSession(); useEffect(() => { diff --git a/pages/admin.tsx b/pages/admin.tsx index 75b6253b..5f2a487c 100644 --- a/pages/admin.tsx +++ b/pages/admin.tsx @@ -2,8 +2,10 @@ import dynamic from 'next/dynamic'; import { Layout } from '../components/Layout'; -const AdminPanel = dynamic(() => - import('../components/AdminPanel/AdminPanel').then(({ AdminPanel }) => ({ default: AdminPanel })), +const AdminPanel = dynamic<{}>(() => + import(/* webpackChunkName: "AdminPanel" */ '../components/AdminPanel/AdminPanel').then( + (mod) => mod.AdminPanel, + ), ); export default function AdminPage() { From 05be6f9262176ae80bbfeb8053c900acfebf2356 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Wi=C5=9Bniewski?= Date: Fri, 1 Jan 2021 18:03:30 +0100 Subject: [PATCH 08/10] Delete next-auth provider --- pages/_app.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pages/_app.tsx b/pages/_app.tsx index 57798a1e..24b55da5 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,7 +1,6 @@ import 'normalize.css/normalize.css'; import '../global.scss'; import '../icomoon-v1.0/style.css'; -import { Provider } from 'next-auth/client'; import { DefaultSeo } from 'next-seo'; import type { AppProps } from 'next/app'; import Head from 'next/head'; @@ -78,9 +77,7 @@ export default function MyApp({ - - - + ); } From a0ea2db40239fdee9e255097a4273659e6a9e3b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Wi=C5=9Bniewski?= Date: Fri, 1 Jan 2021 18:08:08 +0100 Subject: [PATCH 09/10] Fix type annotation --- components/AdminPanel/AdminPanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/AdminPanel/AdminPanel.tsx b/components/AdminPanel/AdminPanel.tsx index 9ada4a08..5561cfb3 100644 --- a/components/AdminPanel/AdminPanel.tsx +++ b/components/AdminPanel/AdminPanel.tsx @@ -5,7 +5,7 @@ import { LoadingScreen } from '../LoadingScreen/LoadingScreen'; import styles from './AdminPanel.module.css'; -export const AdminPanel: React.FC = () => { +export const AdminPanel: React.VFC = () => { const [session, isLoading] = useSession(); useEffect(() => { From 6da04ab16f3f91beae7c5fbae65c1cbaac7b2e50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Wi=C5=9Bniewski?= Date: Fri, 1 Jan 2021 18:24:49 +0100 Subject: [PATCH 10/10] Delete type annotation --- components/AdminPanel/AdminPanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/AdminPanel/AdminPanel.tsx b/components/AdminPanel/AdminPanel.tsx index 5561cfb3..5ce16b27 100644 --- a/components/AdminPanel/AdminPanel.tsx +++ b/components/AdminPanel/AdminPanel.tsx @@ -5,7 +5,7 @@ import { LoadingScreen } from '../LoadingScreen/LoadingScreen'; import styles from './AdminPanel.module.css'; -export const AdminPanel: React.VFC = () => { +export const AdminPanel = () => { const [session, isLoading] = useSession(); useEffect(() => {