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
5 changes: 5 additions & 0 deletions console/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,10 @@ VITE_POLARIS_PRINCIPAL_SCOPE=PRINCIPAL_ROLE:ALL
# VITE_OIDC_REDIRECT_URI=http://localhost:3000/auth/callback
# VITE_OIDC_SCOPE=openid profile email

# Comma-separated list of JWT claims used to resolve the Polaris principal name,
# in order of priority. Defaults to "sub,principal,principal_name,name".
# For Entra ID / Azure AD, use: preferred_username,email,sub,name
# VITE_OIDC_PRINCIPAL_CLAIMS=sub,principal,principal_name,name

# Docker Configuration
PORT=3000
3 changes: 2 additions & 1 deletion console/docker/generate-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ window.APP_CONFIG = {
VITE_OIDC_ISSUER_URL: '${VITE_OIDC_ISSUER_URL}',
VITE_OIDC_CLIENT_ID: '${VITE_OIDC_CLIENT_ID}',
VITE_OIDC_REDIRECT_URI: '${VITE_OIDC_REDIRECT_URI}',
VITE_OIDC_SCOPE: '${VITE_OIDC_SCOPE}'
VITE_OIDC_SCOPE: '${VITE_OIDC_SCOPE}',
VITE_OIDC_PRINCIPAL_CLAIMS: '${VITE_OIDC_PRINCIPAL_CLAIMS}'
};
EOF

Expand Down
5 changes: 5 additions & 0 deletions console/src/lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ interface AppConfig {
VITE_OIDC_CLIENT_ID?: string
VITE_OIDC_REDIRECT_URI?: string
VITE_OIDC_SCOPE?: string
VITE_OIDC_PRINCIPAL_CLAIMS?: string
}

declare global {
Expand Down Expand Up @@ -59,4 +60,8 @@ export const config = {
OIDC_CLIENT_ID: getConfig("VITE_OIDC_CLIENT_ID", ""),
OIDC_REDIRECT_URI: getConfig("VITE_OIDC_REDIRECT_URI", ""),
OIDC_SCOPE: getConfig("VITE_OIDC_SCOPE", "openid profile email"),
OIDC_PRINCIPAL_CLAIMS: getConfig(
"VITE_OIDC_PRINCIPAL_CLAIMS",
"sub,principal,principal_name,name",
),
}
29 changes: 19 additions & 10 deletions console/src/lib/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
import { config } from "@/lib/config"

export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
Expand All @@ -45,8 +46,14 @@ export function decodeJWT(token: string): Record<string, unknown> | null {
}

/**
* Extracts the principal name from a JWT token
* The principal name is typically in the 'sub' (subject) claim
* Extracts the principal name from a JWT token.
* The claims to inspect and their priority order are controlled by the
* VITE_OIDC_PRINCIPAL_CLAIMS environment variable (comma-separated list).
* Defaults to "sub,principal,principal_name,name".
*
* Example for Entra ID / Azure AD:
* VITE_OIDC_PRINCIPAL_CLAIMS=preferred_username,email,sub,name
*
* @param token - The JWT token string
* @returns The principal name or null if not found
*/
Expand All @@ -55,12 +62,14 @@ export function getPrincipalNameFromToken(token: string): string | null {
if (!decoded) {
return null
}
// Try common JWT claim names for the principal/subject
return (
(decoded.sub as string) ||
(decoded.principal as string) ||
(decoded.principal_name as string) ||
(decoded.name as string) ||
null
)
const claims = config.OIDC_PRINCIPAL_CLAIMS.split(",")
.map((c) => c.trim())
.filter(Boolean)
for (const claim of claims) {
const value = decoded[claim]
if (typeof value === "string" && value) {
return value
}
}
return null
}