feat: add login and print user object on my-pages
This commit is contained in:
committed by
Simon Emanuelsson
parent
f1278a8d11
commit
70f9c22410
@@ -2,7 +2,13 @@ CMS_ACCESS_TOKEN=""
|
||||
CMS_API_KEY=""
|
||||
CMS_ENVIRONMENT="development"
|
||||
CMS_URL="https://eu-graphql.contentstack.com/stacks/${CMS_API_KEY}?environment=${CMS_ENVIRONMENT}"
|
||||
CMS_PREVIEW_URL="https://graphql-preview.contentstack.com/stacks/${CMS_API_KEY}?environment=${CMS_ENVIRONMENT}";
|
||||
CMS_PREVIEW_URL="https://graphql-preview.contentstack.com/stacks/${CMS_API_KEY}?environment=${CMS_ENVIRONMENT}"
|
||||
CMS_PREVIEW_TOKEN=""
|
||||
ADOBE_SCRIPT_SRC=""
|
||||
REVALIDATE_SECRET=""
|
||||
DESIGN_SYSTEM_ACCESS_TOKEN=""
|
||||
CURITY_CLIENT_ID_USER=""
|
||||
CURITY_CLIENT_SECRET_USER=""
|
||||
CURITY_ISSUER_USER="https://testlogin.scandichotels.com"
|
||||
NEXTAUTH_URL="http://localhost:3000/api/auth"
|
||||
NEXTAUTH_SECRET="secret"
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -34,3 +34,5 @@ yarn-error.log*
|
||||
# typescript
|
||||
*.tsbuildinfo
|
||||
next-env.d.ts
|
||||
|
||||
certificates
|
||||
12
app/[lang]/(live)/(protected)/my-pages/page.tsx
Normal file
12
app/[lang]/(live)/(protected)/my-pages/page.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import { auth } from "@/auth"
|
||||
|
||||
export default async function MyPages() {
|
||||
const session = await auth()
|
||||
console.log({ session })
|
||||
return (
|
||||
<>
|
||||
<h2>Wilkommen</h2>
|
||||
<pre>{JSON.stringify(session, null, 2)}</pre>
|
||||
</>
|
||||
)
|
||||
}
|
||||
21
app/[lang]/(live)/(public)/login/page.tsx
Normal file
21
app/[lang]/(live)/(public)/login/page.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { signIn } from "@/auth"
|
||||
import { pageNames } from "@/constants/myPages"
|
||||
|
||||
import type { LangParams, Params } from "@/types/params"
|
||||
|
||||
export default async function Page({ params }: Params<LangParams>) {
|
||||
async function login() {
|
||||
"use server"
|
||||
await signIn("curity", {
|
||||
redirectTo: `/${params.lang}/${pageNames[params.lang]}`,
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<main>
|
||||
<form action={login}>
|
||||
<button type="submit">Sign In</button>
|
||||
</form>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
2
app/api/auth/[...nextauth]/route.ts
Normal file
2
app/api/auth/[...nextauth]/route.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export { GET, POST } from "@/auth"
|
||||
export const runtime = "edge"
|
||||
@@ -1,7 +1,7 @@
|
||||
import { env } from "@/env/server"
|
||||
import { revalidateTag } from "next/cache"
|
||||
|
||||
import type { NextRequest } from "next/server"
|
||||
import { NextRequest } from "next/server"
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
|
||||
116
auth.ts
Normal file
116
auth.ts
Normal file
@@ -0,0 +1,116 @@
|
||||
import NextAuth from "next-auth"
|
||||
|
||||
import { env } from "@/env/server"
|
||||
|
||||
import type { NextAuthConfig } from "next-auth"
|
||||
|
||||
export const config = {
|
||||
providers: [
|
||||
{
|
||||
id: "curity",
|
||||
type: "oidc",
|
||||
name: "Curity",
|
||||
// FIXME: This is incorrect. We should not hard code this.
|
||||
// It should be ${env.CURITY_ISSUER_USER}.
|
||||
// This change requires sync between Curity deploy and CurrentWeb and NewWeb.
|
||||
issuer: "https://scandichotels.com",
|
||||
token: {
|
||||
url: `${env.CURITY_ISSUER_USER}/oauth/v2/token`,
|
||||
},
|
||||
userinfo: {
|
||||
url: `${env.CURITY_ISSUER_USER}/oauth/v2/userinfo`,
|
||||
},
|
||||
authorization: {
|
||||
url: `${env.CURITY_ISSUER_USER}/oauth/v2/authorize`,
|
||||
params: {
|
||||
scope: ["openid"],
|
||||
},
|
||||
},
|
||||
clientId: env.CURITY_CLIENT_ID_USER,
|
||||
clientSecret: env.CURITY_CLIENT_SECRET_USER,
|
||||
|
||||
profile(profile: { id: string; sub: string; given_name: string }) {
|
||||
console.log({ profile })
|
||||
return {
|
||||
id: profile.id,
|
||||
sub: profile.sub,
|
||||
given_name: profile.given_name,
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
trustHost: true,
|
||||
// pages: {
|
||||
// signIn: "/auth/login",
|
||||
// },
|
||||
// basePath: "/api/auth",
|
||||
session: {
|
||||
strategy: "jwt",
|
||||
},
|
||||
callbacks: {
|
||||
async signIn(...args) {
|
||||
console.log("****** SIGN IN *******")
|
||||
console.log(args)
|
||||
return true
|
||||
},
|
||||
async session(...args) {
|
||||
console.log(args)
|
||||
return args[0].session
|
||||
},
|
||||
async redirect({ baseUrl, url }) {
|
||||
console.log("****** REDIRECT *******")
|
||||
console.log({ url })
|
||||
console.log({ baseUrl })
|
||||
// Allows relative callback URLs
|
||||
if (url.startsWith("/")) {
|
||||
return `${baseUrl}${url}`
|
||||
} else if (new URL(url).origin === baseUrl) {
|
||||
// Allows callback URLs on the same origin
|
||||
return url
|
||||
}
|
||||
return baseUrl
|
||||
},
|
||||
authorized({ auth, request }) {
|
||||
console.log("****** AUTHORIZED *******")
|
||||
console.log({ request, auth })
|
||||
// const { pathname } = request.nextUrl
|
||||
// if (pathname === "/middleware-example") return !!auth
|
||||
return true
|
||||
},
|
||||
jwt({ session, token, trigger }) {
|
||||
console.log("****** JWT *******")
|
||||
// if (trigger === "update") token.name = session.user.name
|
||||
console.log({ token, trigger, session })
|
||||
return token
|
||||
},
|
||||
},
|
||||
events: {
|
||||
async signIn(...args) {
|
||||
console.log({ args })
|
||||
},
|
||||
async session(...args) {
|
||||
console.log({ args })
|
||||
},
|
||||
},
|
||||
logger: {
|
||||
error(code, ...message) {
|
||||
console.info("ERROR LOGGER")
|
||||
console.error(code, message)
|
||||
},
|
||||
warn(code, ...message) {
|
||||
console.info("WARN LOGGER")
|
||||
console.warn(code, message)
|
||||
},
|
||||
debug(code, ...message) {
|
||||
console.info("DEBUG LOGGER")
|
||||
console.debug(code, message)
|
||||
},
|
||||
},
|
||||
} satisfies NextAuthConfig
|
||||
|
||||
export const {
|
||||
handlers: { GET, POST },
|
||||
auth,
|
||||
signIn,
|
||||
signOut,
|
||||
} = NextAuth(config)
|
||||
@@ -1,4 +1,4 @@
|
||||
import { langEnum } from "@/types/lang"
|
||||
import { langEnum, type Lang } from "@/types/lang"
|
||||
|
||||
export const localeToLang = {
|
||||
en: langEnum.en,
|
||||
@@ -39,3 +39,13 @@ export const localeToLang = {
|
||||
"nn-NO": langEnum.no,
|
||||
"se-NO": langEnum.no,
|
||||
}
|
||||
|
||||
export const DEFAULT_LOCALE = "en"
|
||||
export const locales: Lang[] = ["da", "de", DEFAULT_LOCALE, "fi", "no", "sv"]
|
||||
|
||||
export function findLocale(pathname: string) {
|
||||
let locale = locales.find(
|
||||
(loc) => pathname.startsWith(`/${loc}/`) || pathname === `/${loc}`
|
||||
)
|
||||
return locale
|
||||
}
|
||||
|
||||
8
constants/myPages.js
Normal file
8
constants/myPages.js
Normal file
@@ -0,0 +1,8 @@
|
||||
export const pageNames = {
|
||||
da: "mine-sider",
|
||||
de: "mein-profil",
|
||||
en: "my-pages",
|
||||
fi: "minun-sivujani",
|
||||
no: "mine-sider",
|
||||
sv: "mina-sidor",
|
||||
}
|
||||
10
constants/myPages.ts
Normal file
10
constants/myPages.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { Lang } from "@/types/lang"
|
||||
|
||||
export const pageNames: Record<Lang, string> = {
|
||||
da: "mine-sider",
|
||||
de: "mein-profil",
|
||||
en: "my-pages",
|
||||
fi: "minun-sivujani",
|
||||
no: "mine-sider",
|
||||
sv: "mina-sidor",
|
||||
}
|
||||
6
env/server.ts
vendored
6
env/server.ts
vendored
@@ -16,6 +16,9 @@ export const env = createEnv({
|
||||
PRINT_QUERY: z.boolean().default(false),
|
||||
REVALIDATE_SECRET: z.string(),
|
||||
DESIGN_SYSTEM_ACCESS_TOKEN: z.string(),
|
||||
CURITY_CLIENT_ID_USER: z.string(),
|
||||
CURITY_CLIENT_SECRET_USER: z.string(),
|
||||
CURITY_ISSUER_USER: z.string(),
|
||||
},
|
||||
emptyStringAsUndefined: true,
|
||||
runtimeEnv: {
|
||||
@@ -32,5 +35,8 @@ export const env = createEnv({
|
||||
PRINT_QUERY: process.env.PRINT_QUERY,
|
||||
REVALIDATE_SECRET: process.env.REVALIDATE_SECRET,
|
||||
DESIGN_SYSTEM_ACCESS_TOKEN: process.env.DESIGN_SYSTEM_ACCESS_TOKEN,
|
||||
CURITY_CLIENT_ID_USER: process.env.CURITY_CLIENT_ID_USER,
|
||||
CURITY_CLIENT_SECRET_USER: process.env.CURITY_CLIENT_SECRET_USER,
|
||||
CURITY_ISSUER_USER: process.env.CURITY_ISSUER_USER,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -1,42 +1,63 @@
|
||||
import { NextResponse } from "next/server"
|
||||
import type { NextRequest } from "next/server"
|
||||
|
||||
// This function can be marked `async` if using `await` inside
|
||||
export async function middleware(request: NextRequest) {
|
||||
// const locales = await fetch(CMS_API, {
|
||||
// locales: true
|
||||
// })
|
||||
const locales = ["en", "sv", "no", "fi", "da", "de"]
|
||||
import { auth } from "@/auth"
|
||||
|
||||
const locale = locales.find(
|
||||
(locale) =>
|
||||
request.nextUrl.pathname.startsWith(`/${locale}/`) ||
|
||||
request.nextUrl.pathname === `/${locale}`
|
||||
)
|
||||
import { findLocale } from "@/constants/locales"
|
||||
import { pageNames } from "@/constants/myPages"
|
||||
|
||||
import { apiAuthPrefix } from "@/routes/api"
|
||||
// import { publicRoutes } from "@/routes/public"
|
||||
import { protectedRoutes } from "@/routes/protected"
|
||||
|
||||
export default auth(async function middleware(request) {
|
||||
const { nextUrl } = request
|
||||
const isLoggedIn = !!request.auth
|
||||
|
||||
const isApiRoute = nextUrl.pathname.startsWith(apiAuthPrefix)
|
||||
if (isApiRoute) {
|
||||
return NextResponse.next()
|
||||
}
|
||||
|
||||
const locale = findLocale(nextUrl.pathname)
|
||||
if (!locale) {
|
||||
//return <LocalePicker />
|
||||
return Response.json("Not found!!!", { status: 404 })
|
||||
}
|
||||
|
||||
// const data = await fetch(CMS_API, {
|
||||
// uri: request.nextUrl.pathname,
|
||||
// locale
|
||||
// }).json()
|
||||
const isProtectedRoute = protectedRoutes.includes(nextUrl.pathname)
|
||||
if (isProtectedRoute) {
|
||||
if (isLoggedIn) {
|
||||
/**
|
||||
* Temporary hard rewrite to my pages
|
||||
*/
|
||||
return NextResponse.rewrite(
|
||||
new URL(`/${locale}/${pageNames[locale]}`, nextUrl)
|
||||
)
|
||||
} else {
|
||||
/**
|
||||
* Redirect to Loginpage
|
||||
* (Loginpage most likely to be removed)
|
||||
*/
|
||||
return NextResponse.redirect(new URL(`/${locale}/login`, nextUrl))
|
||||
}
|
||||
}
|
||||
|
||||
if (nextUrl.pathname.startsWith(`/${locale}/login`)) {
|
||||
return NextResponse.next()
|
||||
}
|
||||
|
||||
// const isPublicRoute = publicRoutes.includes(nextUrl.pathname)
|
||||
// if (!isLoggedIn && !isPublicRoute) {
|
||||
// return NextResponse.redirect(new URL(`/${locale}/login`, nextUrl))
|
||||
// }
|
||||
|
||||
//const contentType = data.response.meta.contentType;
|
||||
const contentType = "currentContentPage"
|
||||
|
||||
const pathNameWithoutLocale = request.nextUrl.pathname.replace(
|
||||
`/${locale}`,
|
||||
""
|
||||
)
|
||||
|
||||
const pathNameWithoutLocale = nextUrl.pathname.replace(`/${locale}`, "")
|
||||
const searchParams = new URLSearchParams(request.nextUrl.searchParams)
|
||||
|
||||
if (request.nextUrl.pathname.includes("preview")) {
|
||||
searchParams.set("uri", pathNameWithoutLocale.replace("/preview", ""))
|
||||
|
||||
return NextResponse.rewrite(
|
||||
new URL(
|
||||
`/${locale}/preview-current?${searchParams.toString()}`,
|
||||
@@ -46,7 +67,6 @@ export async function middleware(request: NextRequest) {
|
||||
}
|
||||
|
||||
searchParams.set("uri", pathNameWithoutLocale)
|
||||
|
||||
switch (contentType) {
|
||||
case "currentContentPage":
|
||||
return NextResponse.rewrite(
|
||||
@@ -56,19 +76,16 @@ export async function middleware(request: NextRequest) {
|
||||
)
|
||||
)
|
||||
}
|
||||
return NextResponse.redirect(new URL("/home", request.url))
|
||||
}
|
||||
|
||||
return NextResponse.next()
|
||||
})
|
||||
|
||||
// See "Matching Paths" below to learn more
|
||||
export const config = {
|
||||
matcher: [
|
||||
/*
|
||||
* Match all request paths except for the ones starting with:
|
||||
* - api (API routes)
|
||||
* - _next/static (static files)
|
||||
* - _next/image (image optimization files)
|
||||
* - favicon.ico (favicon file)
|
||||
/**
|
||||
* Copied from Clerk to protect all routes by default and handle
|
||||
* public routes inside middleware.
|
||||
* (https://clerk.com/docs/quickstarts/nextjs?utm_source=sponsorship&utm_medium=youtube&utm_campaign=code-with-antonio&utm_content=12-31-2023#add-authentication-to-your-app)
|
||||
*/
|
||||
"/((?!api|_next/static|_next/image|_static|imageVault|contentassets|favicon.ico|en/test).*)",
|
||||
],
|
||||
matcher: ["/((?!.+\\.[\\w]+$|_next|en/test).*)", "/", "/(api)(.*)"],
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import createJiti from "jiti"
|
||||
|
||||
import { pageNames } from "./constants/myPages.js"
|
||||
const jiti = createJiti(new URL(import.meta.url).pathname)
|
||||
|
||||
jiti("./env/server")
|
||||
@@ -9,10 +9,6 @@ jiti("./env/client")
|
||||
const nextConfig = {
|
||||
eslint: { ignoreDuringBuilds: true },
|
||||
|
||||
generateBuildId: async () => {
|
||||
return process.env.BUILD_ID
|
||||
},
|
||||
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{
|
||||
@@ -40,6 +36,17 @@ const nextConfig = {
|
||||
|
||||
return config
|
||||
},
|
||||
rewrites() {
|
||||
return {
|
||||
beforeFiles: [
|
||||
{ source: `/da/${pageNames.da}`, destination: "/da/my-pages" },
|
||||
{ source: `/de/${pageNames.de}`, destination: "/de/my-pages" },
|
||||
{ source: `/fi/${pageNames.fi}`, destination: "/fi/my-pages" },
|
||||
{ source: `/no/${pageNames.no}`, destination: "/no/my-pages" },
|
||||
{ source: `/sv/${pageNames.sv}`, destination: "/sv/my-pages" },
|
||||
],
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
export default nextConfig
|
||||
|
||||
119
package-lock.json
generated
119
package-lock.json
generated
@@ -18,6 +18,7 @@
|
||||
"graphql-request": "^6.1.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"next": "^14.1.0",
|
||||
"next-auth": "^5.0.0-beta.15",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"server-only": "^0.0.1",
|
||||
@@ -52,6 +53,36 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@auth/core": {
|
||||
"version": "0.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@auth/core/-/core-0.28.0.tgz",
|
||||
"integrity": "sha512-/fh/tb/L4NMSYcyPoo4Imn8vN6MskcVfgESF8/ndgtI4fhD/7u7i5fTVzWgNRZ4ebIEGHNDbWFRxaTu1NtQgvA==",
|
||||
"dependencies": {
|
||||
"@panva/hkdf": "^1.1.1",
|
||||
"@types/cookie": "0.6.0",
|
||||
"cookie": "0.6.0",
|
||||
"jose": "^5.1.3",
|
||||
"oauth4webapi": "^2.4.0",
|
||||
"preact": "10.11.3",
|
||||
"preact-render-to-string": "5.2.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@simplewebauthn/browser": "^9.0.1",
|
||||
"@simplewebauthn/server": "^9.0.2",
|
||||
"nodemailer": "^6.8.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@simplewebauthn/browser": {
|
||||
"optional": true
|
||||
},
|
||||
"@simplewebauthn/server": {
|
||||
"optional": true
|
||||
},
|
||||
"nodemailer": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.23.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz",
|
||||
@@ -625,6 +656,14 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/@panva/hkdf": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@panva/hkdf/-/hkdf-1.1.1.tgz",
|
||||
"integrity": "sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/panva"
|
||||
}
|
||||
},
|
||||
"node_modules/@pkgjs/parseargs": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||
@@ -2268,6 +2307,11 @@
|
||||
"@types/responselike": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/cookie": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
|
||||
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA=="
|
||||
},
|
||||
"node_modules/@types/http-cache-semantics": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
|
||||
@@ -3692,6 +3736,14 @@
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz",
|
||||
"integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookies": {
|
||||
"version": "0.9.1",
|
||||
"resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz",
|
||||
@@ -6513,6 +6565,14 @@
|
||||
"@sideway/pinpoint": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jose": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-5.2.3.tgz",
|
||||
"integrity": "sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/panva"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
@@ -7749,6 +7809,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/next-auth": {
|
||||
"version": "5.0.0-beta.15",
|
||||
"resolved": "https://registry.npmjs.org/next-auth/-/next-auth-5.0.0-beta.15.tgz",
|
||||
"integrity": "sha512-UQggNq8CDu3/w8CYkihKLLnRPNXel98K0j7mtjj9a6XTNYo4Hni8xg/2h1YhElW6vXE8mgtvmH11rU8NKw86jQ==",
|
||||
"dependencies": {
|
||||
"@auth/core": "0.28.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@simplewebauthn/browser": "^9.0.1",
|
||||
"@simplewebauthn/server": "^9.0.2",
|
||||
"next": "^14",
|
||||
"nodemailer": "^6.6.5",
|
||||
"react": "^18.2.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@simplewebauthn/browser": {
|
||||
"optional": true
|
||||
},
|
||||
"@simplewebauthn/server": {
|
||||
"optional": true
|
||||
},
|
||||
"nodemailer": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/node-fetch": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||
@@ -7828,6 +7914,14 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/oauth4webapi": {
|
||||
"version": "2.10.3",
|
||||
"resolved": "https://registry.npmjs.org/oauth4webapi/-/oauth4webapi-2.10.3.tgz",
|
||||
"integrity": "sha512-9FkXEXfzVKzH63GUOZz1zMr3wBaICSzk6DLXx+CGdrQ10ItNk2ePWzYYc1fdmKq1ayGFb2aX97sRCoZ2s0mkDw==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/panva"
|
||||
}
|
||||
},
|
||||
"node_modules/object-assign": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||
@@ -8306,6 +8400,26 @@
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/preact": {
|
||||
"version": "10.11.3",
|
||||
"resolved": "https://registry.npmjs.org/preact/-/preact-10.11.3.tgz",
|
||||
"integrity": "sha512-eY93IVpod/zG3uMF22Unl8h9KkrcKIRs2EGar8hwLZZDU1lkjph303V9HZBwufh2s736U6VXuhD109LYqPoffg==",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/preact"
|
||||
}
|
||||
},
|
||||
"node_modules/preact-render-to-string": {
|
||||
"version": "5.2.3",
|
||||
"resolved": "https://registry.npmjs.org/preact-render-to-string/-/preact-render-to-string-5.2.3.tgz",
|
||||
"integrity": "sha512-aPDxUn5o3GhWdtJtW0svRC2SS/l8D9MAgo2+AWml+BhDImb27ALf04Q2d+AHqUUOc6RdSXFIBVa2gxzgMKgtZA==",
|
||||
"dependencies": {
|
||||
"pretty-format": "^3.8.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"preact": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/prelude-ls": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||
@@ -8342,6 +8456,11 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/pretty-format": {
|
||||
"version": "3.8.0",
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-3.8.0.tgz",
|
||||
"integrity": "sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew=="
|
||||
},
|
||||
"node_modules/process": {
|
||||
"version": "0.11.10",
|
||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "next build",
|
||||
"dev": "next dev",
|
||||
"dev": "rm -rf .next && next dev",
|
||||
"lint": "next lint && tsc",
|
||||
"prepare": "husky install",
|
||||
"start": "node .next/standalone/server.js",
|
||||
@@ -26,6 +26,7 @@
|
||||
"graphql-request": "^6.1.0",
|
||||
"graphql-tag": "^2.12.6",
|
||||
"next": "^14.1.0",
|
||||
"next-auth": "^5.0.0-beta.15",
|
||||
"react": "^18",
|
||||
"react-dom": "^18",
|
||||
"server-only": "^0.0.1",
|
||||
|
||||
1
routes/api.ts
Normal file
1
routes/api.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const apiAuthPrefix = "/api/auth"
|
||||
10
routes/protected.ts
Normal file
10
routes/protected.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { pageNames } from "@/constants/myPages"
|
||||
|
||||
import type { Lang } from "@/types/lang"
|
||||
|
||||
/* Authenticated routes */
|
||||
export const protectedRoutes: string[] = [
|
||||
...Object.keys(pageNames).map(
|
||||
(locale) => `/${locale}/${pageNames[locale as Lang]}`
|
||||
),
|
||||
]
|
||||
2
routes/public.ts
Normal file
2
routes/public.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
/* Unauthenticated routes */
|
||||
export const publicRoutes: string[] = ["/"]
|
||||
Reference in New Issue
Block a user