84 lines
2.3 KiB
TypeScript
84 lines
2.3 KiB
TypeScript
import type { KeycloakConfig, TokenResponse, UserInfo } from '~/utils/types';
|
|
|
|
export class KeycloakClient {
|
|
private config: KeycloakConfig;
|
|
|
|
constructor(config: KeycloakConfig) {
|
|
this.config = config;
|
|
}
|
|
|
|
getAuthUrl(state: string): string {
|
|
const params = new URLSearchParams({
|
|
client_id: this.config.clientId,
|
|
redirect_uri: this.config.callbackUrl,
|
|
response_type: 'code',
|
|
scope: 'openid email profile',
|
|
state,
|
|
});
|
|
|
|
return `${this.config.issuer}/protocol/openid-connect/auth?${params}`;
|
|
}
|
|
|
|
async exchangeCodeForTokens(code: string): Promise<TokenResponse> {
|
|
const response = await fetch(`${this.config.issuer}/protocol/openid-connect/token`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
},
|
|
body: new URLSearchParams({
|
|
grant_type: 'authorization_code',
|
|
client_id: this.config.clientId,
|
|
client_secret: this.config.clientSecret,
|
|
code,
|
|
redirect_uri: this.config.callbackUrl,
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Token exchange failed: ${response.statusText}`);
|
|
}
|
|
|
|
return response.json();
|
|
}
|
|
|
|
async getUserInfo(accessToken: string): Promise<UserInfo> {
|
|
const response = await fetch(`${this.config.issuer}/protocol/openid-connect/userinfo`, {
|
|
headers: {
|
|
Authorization: `Bearer ${accessToken}`,
|
|
},
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to get user info: ${response.statusText}`);
|
|
}
|
|
|
|
return response.json();
|
|
}
|
|
|
|
async refreshToken(refreshToken: string): Promise<TokenResponse> {
|
|
const response = await fetch(`${this.config.issuer}/protocol/openid-connect/token`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/x-www-form-urlencoded',
|
|
},
|
|
body: new URLSearchParams({
|
|
grant_type: 'refresh_token',
|
|
client_id: this.config.clientId,
|
|
client_secret: this.config.clientSecret,
|
|
refresh_token: refreshToken,
|
|
}),
|
|
});
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Token refresh failed: ${response.statusText}`);
|
|
}
|
|
|
|
return response.json();
|
|
}
|
|
}
|
|
|
|
export function createKeycloakClient(): KeycloakClient {
|
|
const config = useRuntimeConfig();
|
|
return new KeycloakClient(config.keycloak);
|
|
}
|