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_API_KEY=""
|
||||||
CMS_ENVIRONMENT="development"
|
CMS_ENVIRONMENT="development"
|
||||||
CMS_URL="https://eu-graphql.contentstack.com/stacks/${CMS_API_KEY}?environment=${CMS_ENVIRONMENT}"
|
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=""
|
CMS_PREVIEW_TOKEN=""
|
||||||
ADOBE_SCRIPT_SRC=""
|
ADOBE_SCRIPT_SRC=""
|
||||||
|
REVALIDATE_SECRET=""
|
||||||
DESIGN_SYSTEM_ACCESS_TOKEN=""
|
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
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
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 { env } from "@/env/server"
|
||||||
import { revalidateTag } from "next/cache"
|
import { revalidateTag } from "next/cache"
|
||||||
|
|
||||||
import type { NextRequest } from "next/server"
|
import { NextRequest } from "next/server"
|
||||||
|
|
||||||
export async function POST(request: NextRequest) {
|
export async function POST(request: NextRequest) {
|
||||||
try {
|
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 = {
|
export const localeToLang = {
|
||||||
en: langEnum.en,
|
en: langEnum.en,
|
||||||
@@ -39,3 +39,13 @@ export const localeToLang = {
|
|||||||
"nn-NO": langEnum.no,
|
"nn-NO": langEnum.no,
|
||||||
"se-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),
|
PRINT_QUERY: z.boolean().default(false),
|
||||||
REVALIDATE_SECRET: z.string(),
|
REVALIDATE_SECRET: z.string(),
|
||||||
DESIGN_SYSTEM_ACCESS_TOKEN: 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,
|
emptyStringAsUndefined: true,
|
||||||
runtimeEnv: {
|
runtimeEnv: {
|
||||||
@@ -32,5 +35,8 @@ export const env = createEnv({
|
|||||||
PRINT_QUERY: process.env.PRINT_QUERY,
|
PRINT_QUERY: process.env.PRINT_QUERY,
|
||||||
REVALIDATE_SECRET: process.env.REVALIDATE_SECRET,
|
REVALIDATE_SECRET: process.env.REVALIDATE_SECRET,
|
||||||
DESIGN_SYSTEM_ACCESS_TOKEN: process.env.DESIGN_SYSTEM_ACCESS_TOKEN,
|
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 { NextResponse } from "next/server"
|
||||||
import type { NextRequest } from "next/server"
|
|
||||||
|
|
||||||
// This function can be marked `async` if using `await` inside
|
import { auth } from "@/auth"
|
||||||
export async function middleware(request: NextRequest) {
|
|
||||||
// const locales = await fetch(CMS_API, {
|
|
||||||
// locales: true
|
|
||||||
// })
|
|
||||||
const locales = ["en", "sv", "no", "fi", "da", "de"]
|
|
||||||
|
|
||||||
const locale = locales.find(
|
import { findLocale } from "@/constants/locales"
|
||||||
(locale) =>
|
import { pageNames } from "@/constants/myPages"
|
||||||
request.nextUrl.pathname.startsWith(`/${locale}/`) ||
|
|
||||||
request.nextUrl.pathname === `/${locale}`
|
|
||||||
)
|
|
||||||
|
|
||||||
|
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) {
|
if (!locale) {
|
||||||
//return <LocalePicker />
|
//return <LocalePicker />
|
||||||
return Response.json("Not found!!!", { status: 404 })
|
return Response.json("Not found!!!", { status: 404 })
|
||||||
}
|
}
|
||||||
|
|
||||||
// const data = await fetch(CMS_API, {
|
const isProtectedRoute = protectedRoutes.includes(nextUrl.pathname)
|
||||||
// uri: request.nextUrl.pathname,
|
if (isProtectedRoute) {
|
||||||
// locale
|
if (isLoggedIn) {
|
||||||
// }).json()
|
/**
|
||||||
|
* 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 = data.response.meta.contentType;
|
||||||
const contentType = "currentContentPage"
|
const contentType = "currentContentPage"
|
||||||
|
const pathNameWithoutLocale = nextUrl.pathname.replace(`/${locale}`, "")
|
||||||
const pathNameWithoutLocale = request.nextUrl.pathname.replace(
|
|
||||||
`/${locale}`,
|
|
||||||
""
|
|
||||||
)
|
|
||||||
|
|
||||||
const searchParams = new URLSearchParams(request.nextUrl.searchParams)
|
const searchParams = new URLSearchParams(request.nextUrl.searchParams)
|
||||||
|
|
||||||
if (request.nextUrl.pathname.includes("preview")) {
|
if (request.nextUrl.pathname.includes("preview")) {
|
||||||
searchParams.set("uri", pathNameWithoutLocale.replace("/preview", ""))
|
searchParams.set("uri", pathNameWithoutLocale.replace("/preview", ""))
|
||||||
|
|
||||||
return NextResponse.rewrite(
|
return NextResponse.rewrite(
|
||||||
new URL(
|
new URL(
|
||||||
`/${locale}/preview-current?${searchParams.toString()}`,
|
`/${locale}/preview-current?${searchParams.toString()}`,
|
||||||
@@ -46,7 +67,6 @@ export async function middleware(request: NextRequest) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
searchParams.set("uri", pathNameWithoutLocale)
|
searchParams.set("uri", pathNameWithoutLocale)
|
||||||
|
|
||||||
switch (contentType) {
|
switch (contentType) {
|
||||||
case "currentContentPage":
|
case "currentContentPage":
|
||||||
return NextResponse.rewrite(
|
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
|
// See "Matching Paths" below to learn more
|
||||||
export const config = {
|
export const config = {
|
||||||
matcher: [
|
/**
|
||||||
/*
|
* Copied from Clerk to protect all routes by default and handle
|
||||||
* Match all request paths except for the ones starting with:
|
* public routes inside middleware.
|
||||||
* - api (API routes)
|
* (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)
|
||||||
* - _next/static (static files)
|
*/
|
||||||
* - _next/image (image optimization files)
|
matcher: ["/((?!.+\\.[\\w]+$|_next|en/test).*)", "/", "/(api)(.*)"],
|
||||||
* - favicon.ico (favicon file)
|
|
||||||
*/
|
|
||||||
"/((?!api|_next/static|_next/image|_static|imageVault|contentassets|favicon.ico|en/test).*)",
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import createJiti from "jiti"
|
import createJiti from "jiti"
|
||||||
|
import { pageNames } from "./constants/myPages.js"
|
||||||
const jiti = createJiti(new URL(import.meta.url).pathname)
|
const jiti = createJiti(new URL(import.meta.url).pathname)
|
||||||
|
|
||||||
jiti("./env/server")
|
jiti("./env/server")
|
||||||
@@ -9,10 +9,6 @@ jiti("./env/client")
|
|||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
eslint: { ignoreDuringBuilds: true },
|
eslint: { ignoreDuringBuilds: true },
|
||||||
|
|
||||||
generateBuildId: async () => {
|
|
||||||
return process.env.BUILD_ID
|
|
||||||
},
|
|
||||||
|
|
||||||
images: {
|
images: {
|
||||||
remotePatterns: [
|
remotePatterns: [
|
||||||
{
|
{
|
||||||
@@ -40,6 +36,17 @@ const nextConfig = {
|
|||||||
|
|
||||||
return config
|
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
|
export default nextConfig
|
||||||
|
|||||||
119
package-lock.json
generated
119
package-lock.json
generated
@@ -18,6 +18,7 @@
|
|||||||
"graphql-request": "^6.1.0",
|
"graphql-request": "^6.1.0",
|
||||||
"graphql-tag": "^2.12.6",
|
"graphql-tag": "^2.12.6",
|
||||||
"next": "^14.1.0",
|
"next": "^14.1.0",
|
||||||
|
"next-auth": "^5.0.0-beta.15",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"server-only": "^0.0.1",
|
"server-only": "^0.0.1",
|
||||||
@@ -52,6 +53,36 @@
|
|||||||
"node": ">=0.10.0"
|
"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": {
|
"node_modules/@babel/runtime": {
|
||||||
"version": "7.23.8",
|
"version": "7.23.8",
|
||||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz",
|
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.8.tgz",
|
||||||
@@ -625,6 +656,14 @@
|
|||||||
"node": ">= 8"
|
"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": {
|
"node_modules/@pkgjs/parseargs": {
|
||||||
"version": "0.11.0",
|
"version": "0.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
|
||||||
@@ -2268,6 +2307,11 @@
|
|||||||
"@types/responselike": "^1.0.0"
|
"@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": {
|
"node_modules/@types/http-cache-semantics": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz",
|
||||||
@@ -3692,6 +3736,14 @@
|
|||||||
"node": ">= 0.6"
|
"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": {
|
"node_modules/cookies": {
|
||||||
"version": "0.9.1",
|
"version": "0.9.1",
|
||||||
"resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/cookies/-/cookies-0.9.1.tgz",
|
||||||
@@ -6513,6 +6565,14 @@
|
|||||||
"@sideway/pinpoint": "^2.0.0"
|
"@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": {
|
"node_modules/js-tokens": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
"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": {
|
"node_modules/node-fetch": {
|
||||||
"version": "2.7.0",
|
"version": "2.7.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
|
||||||
@@ -7828,6 +7914,14 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"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": {
|
"node_modules/object-assign": {
|
||||||
"version": "4.1.1",
|
"version": "4.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
@@ -8306,6 +8400,26 @@
|
|||||||
"node": "^10 || ^12 || >=14"
|
"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": {
|
"node_modules/prelude-ls": {
|
||||||
"version": "1.2.1",
|
"version": "1.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
|
||||||
@@ -8342,6 +8456,11 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"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": {
|
"node_modules/process": {
|
||||||
"version": "0.11.10",
|
"version": "0.11.10",
|
||||||
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
"resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"dev": "next dev",
|
"dev": "rm -rf .next && next dev",
|
||||||
"lint": "next lint && tsc",
|
"lint": "next lint && tsc",
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
"start": "node .next/standalone/server.js",
|
"start": "node .next/standalone/server.js",
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
"graphql-request": "^6.1.0",
|
"graphql-request": "^6.1.0",
|
||||||
"graphql-tag": "^2.12.6",
|
"graphql-tag": "^2.12.6",
|
||||||
"next": "^14.1.0",
|
"next": "^14.1.0",
|
||||||
|
"next-auth": "^5.0.0-beta.15",
|
||||||
"react": "^18",
|
"react": "^18",
|
||||||
"react-dom": "^18",
|
"react-dom": "^18",
|
||||||
"server-only": "^0.0.1",
|
"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