Revert "update"

This reverts commit 5c86afd640.
This commit is contained in:
2026-02-18 20:05:32 +01:00
parent 6b3d0c342e
commit 01502122b2
6 changed files with 45 additions and 39 deletions

View File

@@ -78,6 +78,7 @@ DATABASE_URL="postgresql://user:password@localhost:5432/timetracker"
# OIDC Configuration
OIDC_ISSUER_URL="https://your-oidc-provider.com"
OIDC_CLIENT_ID="your-client-id"
OIDC_REDIRECT_URI="http://localhost:3001/auth/callback"
# Session
SESSION_SECRET="your-secure-session-secret-min-32-chars"

View File

@@ -1,29 +1,30 @@
import { Issuer, generators, Client, TokenSet } from "openid-client";
import { config } from "../config";
import type { AuthenticatedUser } from "../types";
import { Issuer, generators, Client, TokenSet } from 'openid-client';
import { config } from '../config';
import type { AuthenticatedUser } from '../types';
let oidcClient: Client | null = null;
export async function initializeOIDC(): Promise<void> {
try {
const issuer = await Issuer.discover(config.oidc.issuerUrl);
oidcClient = new issuer.Client({
client_id: config.oidc.clientId,
response_types: ["code"],
token_endpoint_auth_method: "none", // PKCE flow - no client secret
redirect_uris: [config.oidc.redirectUri],
response_types: ['code'],
token_endpoint_auth_method: 'none', // PKCE flow - no client secret
});
console.log("OIDC client initialized");
console.log('OIDC client initialized');
} catch (error) {
console.error("Failed to initialize OIDC client:", error);
console.error('Failed to initialize OIDC client:', error);
throw error;
}
}
export function getOIDCClient(): Client {
if (!oidcClient) {
throw new Error("OIDC client not initialized");
throw new Error('OIDC client not initialized');
}
return oidcClient;
}
@@ -45,38 +46,40 @@ export function createAuthSession(): AuthSession {
export function getAuthorizationUrl(session: AuthSession): string {
const client = getOIDCClient();
const codeChallenge = generators.codeChallenge(session.codeVerifier);
return client.authorizationUrl({
scope: "openid profile email",
scope: 'openid profile email',
state: session.state,
nonce: session.nonce,
code_challenge: codeChallenge,
code_challenge_method: "S256",
code_challenge_method: 'S256',
});
}
export async function handleCallback(
params: Record<string, string>,
session: AuthSession,
session: AuthSession
): Promise<TokenSet> {
const client = getOIDCClient();
const tokenSet = await client.callback(undefined, params, {
code_verifier: session.codeVerifier,
state: session.state,
nonce: session.nonce,
});
const tokenSet = await client.callback(
config.oidc.redirectUri,
params,
{
code_verifier: session.codeVerifier,
state: session.state,
nonce: session.nonce,
}
);
return tokenSet;
}
export async function getUserInfo(
tokenSet: TokenSet,
): Promise<AuthenticatedUser> {
export async function getUserInfo(tokenSet: TokenSet): Promise<AuthenticatedUser> {
const client = getOIDCClient();
const claims = tokenSet.claims();
// Try to get more detailed userinfo if available
let userInfo: Record<string, unknown> = {};
try {
@@ -85,21 +88,16 @@ export async function getUserInfo(
// Some providers don't support userinfo endpoint
// We'll use the claims from the ID token
}
const id = String(claims.sub);
const username = String(
userInfo.preferred_username ||
claims.preferred_username ||
claims.name ||
id,
);
const email = String(userInfo.email || claims.email || "");
const fullName = String(userInfo.name || claims.name || "") || null;
const username = String(userInfo.preferred_username || claims.preferred_username || claims.name || id);
const email = String(userInfo.email || claims.email || '');
const fullName = String(userInfo.name || claims.name || '') || null;
if (!email) {
throw new Error("Email not provided by OIDC provider");
throw new Error('Email not provided by OIDC provider');
}
return {
id,
username,
@@ -116,4 +114,4 @@ export async function verifyToken(tokenSet: TokenSet): Promise<boolean> {
} catch {
return false;
}
}
}

View File

@@ -14,6 +14,9 @@ export const config = {
oidc: {
issuerUrl: process.env.OIDC_ISSUER_URL || "",
clientId: process.env.OIDC_CLIENT_ID || "",
redirectUri:
process.env.OIDC_REDIRECT_URI ||
"http://localhost:3001/api/auth/callback",
},
session: {

View File

@@ -23,6 +23,7 @@ services:
DATABASE_URL: "postgresql://timetracker:timetracker_password@db:5432/timetracker"
OIDC_ISSUER_URL: ${OIDC_ISSUER_URL}
OIDC_CLIENT_ID: ${OIDC_CLIENT_ID}
OIDC_REDIRECT_URI: "${API_URL}/auth/callback"
SESSION_SECRET: ${SESSION_SECRET}
PORT: 3001
NODE_ENV: development

View File

@@ -54,6 +54,8 @@ spec:
value: {{ .Values.backend.oidc.issuerUrl | quote }}
- name: OIDC_CLIENT_ID
value: {{ .Values.backend.oidc.clientId | quote }}
- name: OIDC_REDIRECT_URI
value: {{ .Values.backend.oidc.redirectUri | quote }}
- name: SESSION_SECRET
value: {{ .Values.backend.session.secret | quote }}
- name: APP_URL

View File

@@ -41,6 +41,7 @@ backend:
oidc:
issuerUrl: ""
clientId: ""
redirectUri: ""
# Session configuration
session: