Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions .env.local.example
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
NEXT_PUBLIC_SUPABASE_URL=[INSERT SUPABASE PROJECT URL]
NEXT_PUBLIC_SUPABASE_ANON_KEY=[INSERT SUPABASE PROJECT API ANON KEY]
NEXT_PUBLIC_RECAPTCHA_SITE_KEY=[INSERT RECAPTCHA_SITE_KEY]
RECAPTCHA_SECRET_KEY=[INSERT RECAPTCHA_SECRET_KEY]
API_BASE_URL=http://localhost:8080/api
NEXT_PUBLIC_RECAPTCHA_SITE_KEY=6LeoV2MsAAAAALq93j1sqFN8y1WzNpHZHUC7PXGU
RECAPTCHA_SECRET_KEY=6LeoV2MsAAAAAH6o_YnnDgcW4fWYhd2Bvb6_WYZo

API_BASE_URL=http://localhost:8080/api

# The uri that next js will use to build the redirect uri
# The one in authentik provider is https://localhost:8080/auth/
NEXTAUTH_URL=https://localhost:8080

OPENID_CLIENT_SECRET=
OPENID_CLIENT_ID=
OPENID_ISSUER=

AUTH_SECRET=
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
node_modules
/.pnp
.pnp.js
.yarn/install-state.gz
Expand Down Expand Up @@ -36,4 +36,6 @@ yarn-error.log*
next-env.d.ts

.vscode/
.env
.env
certificates
.idea/
112 changes: 112 additions & 0 deletions app/[locale]/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import NextAuth, { AuthOptions } from "next-auth"
import AzureAD from "next-auth/providers/azure-ad"
import Authentik from "next-auth/providers/authentik"
import { JWT } from "next-auth/jwt";

export const authOptions: AuthOptions = {
providers: [
Authentik({
issuer: process.env.OPENID_ISSUER!,
clientId: process.env.OPENID_CLIENT_ID!,
clientSecret: process.env.OPENID_CLIENT_SECRET!/*clientSecret:null!*/,
wellKnown: `${process.env.OPENID_ISSUER!}.well-known/openid-configuration`,
client: {
id_token_signed_response_alg: "HS256",
},
authorization: {params: {scope: "profile email openid offline_access"}}
})
],
secret: process.env.AUTH_SECRET,
callbacks: {

async signIn(user) {
console.log("🚀 ~ file: route.ts ~ line 44 ~ signIn ~ user", user);
return true
},
async jwt({ token, user, account, profile }) {
console.log(token);
if (account) {
return {
...token,
access_token: account.access_token,
refresh_token: account.refresh_token,
expires_at: account.expires_at,
};
}
else if (validToken(token)) {
return token;
}
return await refreshToken(token);
},
async session({ session, token }) {
return { ...session, accessToken: token.accessToken };
},

},
}

const handler = NextAuth(authOptions);

export const GET = handler;
export const POST = handler;

function validToken(token: JWT): boolean{
return (token.expires_at !== undefined && Date.now() < token.expires_at * 1000);
}

async function refreshToken(token: JWT): Promise<JWT>{
if (!token.refresh_token){
throw new Error("No refresh token");
}

const parameters = new URLSearchParams({
"grant_type": "refresh_token",
"refresh_token": token.refresh_token,
"client_id": process.env.OPENID_CLIENT_ID!,
"scope": "profile email openid offline_access"
});

const refreshResponse = await fetch(`${process.env.OPENID_BASE_URL!}token/`, {
method: "POST",
body: parameters.toString(),
headers: {
"Content-Type": "application/x-www-form-urlencoded"
}
});

if (!refreshResponse.ok){
console.log("Failed to refresh");
const text = await refreshResponse.text();
console.log(text);
throw new Error("Failed to refresh token");
}
const response = await refreshResponse.json();

const newToken = response as {
access_token: string
expires_in: number
refresh_token: string
};

const expiration = calculateExpiration(token.expires_at!, newToken.expires_in);

return {
...token,
access_token: newToken.access_token,
refresh_token: newToken.refresh_token,
expires_at: expiration
};
}

function calculateExpiration(formerExpiration: number, expiresIn: number): number {
return Math.floor((Date.now() / 1000) + expiresIn);
}

declare module "next-auth/jwt" {
interface JWT {
access_token?: string
expires_at?: number
refresh_token?: string
error?: "RefreshTokenError"
}
};
20 changes: 0 additions & 20 deletions app/[locale]/auth/callback/route.ts

This file was deleted.

218 changes: 0 additions & 218 deletions app/[locale]/dashboard/accounts/components/UserTable.tsx

This file was deleted.

Loading
Loading