diff --git a/.env.local.example b/.env.local.example
index 3f6c4d543..2f6a2910f 100644
--- a/.env.local.example
+++ b/.env.local.example
@@ -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"
diff --git a/.gitignore b/.gitignore
index fd3dbb571..f69661531 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,3 +34,5 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
+
+certificates
\ No newline at end of file
diff --git a/app/[lang]/(live)/(protected)/my-pages/page.tsx b/app/[lang]/(live)/(protected)/my-pages/page.tsx
new file mode 100644
index 000000000..f567c8dbf
--- /dev/null
+++ b/app/[lang]/(live)/(protected)/my-pages/page.tsx
@@ -0,0 +1,12 @@
+import { auth } from "@/auth"
+
+export default async function MyPages() {
+ const session = await auth()
+ console.log({ session })
+ return (
+ <>
+
Wilkommen
+ {JSON.stringify(session, null, 2)}
+ >
+ )
+}
diff --git a/app/[lang]/(live)/content-page/page.tsx b/app/[lang]/(live)/(public)/content-page/page.tsx
similarity index 100%
rename from app/[lang]/(live)/content-page/page.tsx
rename to app/[lang]/(live)/(public)/content-page/page.tsx
diff --git a/app/[lang]/(live)/(public)/login/page.tsx b/app/[lang]/(live)/(public)/login/page.tsx
new file mode 100644
index 000000000..4c9e43010
--- /dev/null
+++ b/app/[lang]/(live)/(public)/login/page.tsx
@@ -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) {
+ async function login() {
+ "use server"
+ await signIn("curity", {
+ redirectTo: `/${params.lang}/${pageNames[params.lang]}`,
+ })
+ }
+
+ return (
+
+
+
+ )
+}
diff --git a/app/api/auth/[...nextauth]/route.ts b/app/api/auth/[...nextauth]/route.ts
new file mode 100644
index 000000000..bb4896173
--- /dev/null
+++ b/app/api/auth/[...nextauth]/route.ts
@@ -0,0 +1,2 @@
+export { GET, POST } from "@/auth"
+export const runtime = "edge"
diff --git a/app/api/revalidate/route.ts b/app/api/revalidate/route.ts
index e145e87a2..401ee4586 100644
--- a/app/api/revalidate/route.ts
+++ b/app/api/revalidate/route.ts
@@ -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 {
diff --git a/auth.ts b/auth.ts
new file mode 100644
index 000000000..a1d4f9ce2
--- /dev/null
+++ b/auth.ts
@@ -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)
diff --git a/constants/locales.ts b/constants/locales.ts
index 3ba2d1a2a..eb44ed649 100644
--- a/constants/locales.ts
+++ b/constants/locales.ts
@@ -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
+}
diff --git a/constants/myPages.js b/constants/myPages.js
new file mode 100644
index 000000000..4c6684f9e
--- /dev/null
+++ b/constants/myPages.js
@@ -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",
+}
diff --git a/constants/myPages.ts b/constants/myPages.ts
new file mode 100644
index 000000000..7179ba17d
--- /dev/null
+++ b/constants/myPages.ts
@@ -0,0 +1,10 @@
+import type { Lang } from "@/types/lang"
+
+export const pageNames: Record = {
+ da: "mine-sider",
+ de: "mein-profil",
+ en: "my-pages",
+ fi: "minun-sivujani",
+ no: "mine-sider",
+ sv: "mina-sidor",
+}
diff --git a/env/server.ts b/env/server.ts
index 841233153..25d0ddfc9 100644
--- a/env/server.ts
+++ b/env/server.ts
@@ -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,
},
})
diff --git a/middleware.ts b/middleware.ts
index c6aa03dce..217269d2e 100644
--- a/middleware.ts
+++ b/middleware.ts
@@ -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
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)
- */
- "/((?!api|_next/static|_next/image|_static|imageVault|contentassets|favicon.ico|en/test).*)",
- ],
+ /**
+ * 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)
+ */
+ matcher: ["/((?!.+\\.[\\w]+$|_next|en/test).*)", "/", "/(api)(.*)"],
}
diff --git a/next.config.js b/next.config.js
index 8e1c45109..e40cd62d0 100644
--- a/next.config.js
+++ b/next.config.js
@@ -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
diff --git a/package-lock.json b/package-lock.json
index fad4299e5..04d7c91af 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -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",
diff --git a/package.json b/package.json
index ca9e70694..c148072e8 100644
--- a/package.json
+++ b/package.json
@@ -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",
@@ -50,4 +51,4 @@
"engines": {
"node": "18"
}
-}
+}
\ No newline at end of file
diff --git a/routes/api.ts b/routes/api.ts
new file mode 100644
index 000000000..041300c66
--- /dev/null
+++ b/routes/api.ts
@@ -0,0 +1 @@
+export const apiAuthPrefix = "/api/auth"
diff --git a/routes/protected.ts b/routes/protected.ts
new file mode 100644
index 000000000..cb4eca5b7
--- /dev/null
+++ b/routes/protected.ts
@@ -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]}`
+ ),
+]
diff --git a/routes/public.ts b/routes/public.ts
new file mode 100644
index 000000000..fc91de55d
--- /dev/null
+++ b/routes/public.ts
@@ -0,0 +1,2 @@
+/* Unauthenticated routes */
+export const publicRoutes: string[] = ["/"]