mirror of
https://github.com/PeterMaquiran/tvone.git
synced 2026-04-22 20:15:51 +00:00
add auth moodule
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* KEYCLOAK CONFIGURATION
|
||||
* Logic: Environment variable validation and OIDC configuration.
|
||||
*/
|
||||
|
||||
export const keycloakConfig = {
|
||||
clientId: process.env.KEYCLOAK_CLIENT_ID!,
|
||||
clientSecret: process.env.KEYCLOAK_CLIENT_SECRET!,
|
||||
issuer: `${process.env.KEYCLOAK_ISSUER_URL}/realms/${process.env.KEYCLOAK_REALM}`,
|
||||
|
||||
// Scopes needed for OIDC and profile access
|
||||
scope: 'openid profile email',
|
||||
|
||||
// Endpoint for global logout
|
||||
endSessionEndpoint: `${process.env.KEYCLOAK_ISSUER_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/logout`,
|
||||
};
|
||||
|
||||
// Simple check to ensure environment variables are present
|
||||
if (!process.env.KEYCLOAK_CLIENT_ID || !process.env.KEYCLOAK_ISSUER_URL) {
|
||||
console.warn("Auth Warning: Keycloak environment variables are missing.");
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* SESSION MAPPER
|
||||
* Logic: Data transformation (JWT -> Clean Profile).
|
||||
* Purpose: Prevents leaking sensitive JWT metadata to the UI layer.
|
||||
*/
|
||||
|
||||
import { UserProfile, RawKeycloakToken } from '../../types/auth.types';
|
||||
|
||||
export const mapKeycloakProfile = (token: RawKeycloakToken): UserProfile => {
|
||||
return {
|
||||
id: token.sub,
|
||||
name: token.name || 'Guest User',
|
||||
email: token.email,
|
||||
username: token.preferred_username,
|
||||
// Extracting roles for domain-specific logic (e.g., Editor, Admin)
|
||||
roles: token.realm_access?.roles || [],
|
||||
avatar: token.picture || null,
|
||||
// Custom logic to check for premium status
|
||||
isPremium: token.realm_access?.roles.includes('premium_subscriber') ?? false,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
/**
|
||||
* TOKEN REFRESHER
|
||||
* Logic: Silent background token rotation.
|
||||
* Role: Communicates with Keycloak to exchange a Refresh Token for a new Access Token.
|
||||
*/
|
||||
|
||||
import { keycloakConfig } from './keycloak-config';
|
||||
|
||||
export const refreshAccessToken = async (token: any) => {
|
||||
try {
|
||||
const url = `${process.env.KEYCLOAK_ISSUER_URL}/realms/${process.env.KEYCLOAK_REALM}/protocol/openid-connect/token`;
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: new URLSearchParams({
|
||||
client_id: keycloakConfig.clientId,
|
||||
client_secret: keycloakConfig.clientSecret,
|
||||
grant_type: 'refresh_token',
|
||||
refresh_token: token.refreshToken,
|
||||
}),
|
||||
});
|
||||
|
||||
const refreshedTokens = await response.json();
|
||||
|
||||
if (!response.ok) throw refreshedTokens;
|
||||
|
||||
return {
|
||||
...token,
|
||||
accessToken: refreshedTokens.access_token,
|
||||
accessTokenExpires: Date.now() + refreshedTokens.expires_in * 1000,
|
||||
refreshToken: refreshedTokens.refresh_token ?? token.refreshToken, // Fallback to old refresh token
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('Error refreshing access token', error);
|
||||
return {
|
||||
...token,
|
||||
error: 'RefreshAccessTokenError',
|
||||
};
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user