up login page
This commit is contained in:
parent
92cbbb1595
commit
3b95c7871c
49 changed files with 12320 additions and 43 deletions
|
@ -0,0 +1,15 @@
|
|||
import {TestBed} from '@angular/core/testing';
|
||||
import {CognitoAuthService} from './cognito-auth.service';
|
||||
|
||||
describe('CognitoAuthService', () => {
|
||||
let service: CognitoAuthService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({});
|
||||
service = TestBed.inject(CognitoAuthService);
|
||||
});
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
});
|
220
my-workspace/projects/sae-lib/services/cognito-auth.service.ts
Normal file
220
my-workspace/projects/sae-lib/services/cognito-auth.service.ts
Normal file
|
@ -0,0 +1,220 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
|
||||
export type CognitoAuthProvider = 'amplify' | 'oidc';
|
||||
|
||||
export interface CognitoAuthConfig {
|
||||
provider: CognitoAuthProvider;
|
||||
region: string;
|
||||
userPoolId: string;
|
||||
userPoolWebClientId: string;
|
||||
domain: string;
|
||||
redirectSignIn: string;
|
||||
redirectSignOut: string;
|
||||
scopes: string[];
|
||||
requireAuth?: boolean;
|
||||
}
|
||||
|
||||
interface AuthProviderApi {
|
||||
initialize(configuration: CognitoAuthConfig): Promise<void>;
|
||||
signIn(): Promise<void>;
|
||||
signOut(): Promise<void>;
|
||||
isAuthenticated(): Promise<boolean>;
|
||||
getIdToken(): Promise<string | null>;
|
||||
getAccessToken(): Promise<string | null>;
|
||||
handleCallback(): Promise<void>;
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class CognitoAuthService implements AuthProviderApi {
|
||||
private configuration: CognitoAuthConfig | null = null;
|
||||
private activeProvider: CognitoAuthProvider | null = null;
|
||||
|
||||
async initialize(configuration: CognitoAuthConfig): Promise<void> {
|
||||
this.configuration = configuration;
|
||||
this.activeProvider = configuration.provider;
|
||||
|
||||
if (configuration.provider === 'amplify') {
|
||||
const { Amplify } = await import('aws-amplify');
|
||||
Amplify.configure({
|
||||
Auth: {
|
||||
region: configuration.region,
|
||||
userPoolId: configuration.userPoolId,
|
||||
userPoolWebClientId: configuration.userPoolWebClientId,
|
||||
oauth: {
|
||||
domain: configuration.domain,
|
||||
scope: configuration.scopes,
|
||||
redirectSignIn: configuration.redirectSignIn,
|
||||
redirectSignOut: configuration.redirectSignOut,
|
||||
responseType: 'code'
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (configuration.provider === 'oidc') {
|
||||
// Configuration du provider OIDC via angular-oauth2-oidc.
|
||||
// On s'attend à ce que l'app configure OAuthService au bootstrap
|
||||
// (loadDiscoveryDocumentAndLogin, etc.). Ici, rien à faire si ce n'est valider la présence.
|
||||
const { OAuthService } = await import('angular-oauth2-oidc');
|
||||
const injector = (window as any).ngInjector;
|
||||
if (!injector) {
|
||||
throw new Error('Injector Angular global introuvable. Exposez window.ngInjector au bootstrap.');
|
||||
}
|
||||
const oauthService = injector.get(OAuthService);
|
||||
if (!oauthService) {
|
||||
throw new Error('OAuthService non disponible. Vérifiez l\'installation et la configuration angular-oauth2-oidc.');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
throw new Error('Provider non pris en charge. Utilisez "amplify" ou "oidc".');
|
||||
}
|
||||
|
||||
async signIn(): Promise<void> {
|
||||
this.assertInitialized();
|
||||
if (this.activeProvider === 'amplify') {
|
||||
const { Auth } = await import('aws-amplify');
|
||||
await Auth.federatedSignIn();
|
||||
return;
|
||||
}
|
||||
if (this.activeProvider === 'oidc') {
|
||||
const { OAuthService } = await import('angular-oauth2-oidc');
|
||||
const injector = (window as any).ngInjector;
|
||||
const oauthService = injector.get(OAuthService);
|
||||
oauthService.initLoginFlow();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
async signOut(): Promise<void> {
|
||||
this.assertInitialized();
|
||||
if (this.activeProvider === 'amplify') {
|
||||
const { Auth } = await import('aws-amplify');
|
||||
await Auth.signOut();
|
||||
return;
|
||||
}
|
||||
if (this.activeProvider === 'oidc') {
|
||||
const { OAuthService } = await import('angular-oauth2-oidc');
|
||||
const injector = (window as any).ngInjector;
|
||||
const oauthService = injector.get(OAuthService);
|
||||
oauthService.logOut();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
async isAuthenticated(): Promise<boolean> {
|
||||
this.assertInitialized();
|
||||
if (this.activeProvider === 'amplify') {
|
||||
try {
|
||||
const { Auth } = await import('aws-amplify');
|
||||
const session = await Auth.currentSession();
|
||||
return !!session?.getIdToken()?.getJwtToken();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.activeProvider === 'oidc') {
|
||||
try {
|
||||
const { OAuthService } = await import('angular-oauth2-oidc');
|
||||
const injector = (window as any).ngInjector;
|
||||
const oauthService = injector.get(OAuthService);
|
||||
return oauthService.hasValidAccessToken() || oauthService.hasValidIdToken();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
async getIdToken(): Promise<string | null> {
|
||||
this.assertInitialized();
|
||||
if (this.activeProvider === 'amplify') {
|
||||
try {
|
||||
const { Auth } = await import('aws-amplify');
|
||||
const session = await Auth.currentSession();
|
||||
return session.getIdToken().getJwtToken() ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.activeProvider === 'oidc') {
|
||||
try {
|
||||
const { OAuthService } = await import('angular-oauth2-oidc');
|
||||
const injector = (window as any).ngInjector;
|
||||
const oauthService = injector.get(OAuthService);
|
||||
return oauthService.getIdToken() ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async getAccessToken(): Promise<string | null> {
|
||||
this.assertInitialized();
|
||||
if (this.activeProvider === 'amplify') {
|
||||
try {
|
||||
const { Auth } = await import('aws-amplify');
|
||||
const session = await Auth.currentSession();
|
||||
return session.getAccessToken().getJwtToken() ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (this.activeProvider === 'oidc') {
|
||||
try {
|
||||
const { OAuthService } = await import('angular-oauth2-oidc');
|
||||
const injector = (window as any).ngInjector;
|
||||
const oauthService = injector.get(OAuthService);
|
||||
return oauthService.getAccessToken() ?? null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
async handleCallback(): Promise<void> {
|
||||
this.assertInitialized();
|
||||
if (this.activeProvider === 'amplify') {
|
||||
// Amplify gère l'échange code->tokens automatiquement lors du retour.
|
||||
// Appeler currentSession() force la résolution de la session.
|
||||
const { Auth } = await import('aws-amplify');
|
||||
await Auth.currentSession();
|
||||
return;
|
||||
}
|
||||
if (this.activeProvider === 'oidc') {
|
||||
// Pour angular-oauth2-oidc, la prise en charge est faite au bootstrap avec
|
||||
// loadDiscoveryDocumentAndLogin(). Rien à faire ici si c'est déjà configuré.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
async ensureAuthenticated(loginRoute: string): Promise<boolean> {
|
||||
const isAuthed = await this.isAuthenticated();
|
||||
if (isAuthed) {
|
||||
return true;
|
||||
}
|
||||
if (this.configuration?.requireAuth) {
|
||||
// Redirection douce vers la page de login Angular
|
||||
window.location.assign(loginRoute);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private assertInitialized(): void {
|
||||
if (!this.configuration || !this.activeProvider) {
|
||||
throw new Error('CognitoAuthService non initialisé. Appelez initialize(config).');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue