Files
openstapps/frontend/app/src/app/modules/profile/id-cards.provider.ts

85 lines
3.0 KiB
TypeScript

import {Injectable} from '@angular/core';
import {SCIdCard, SCThingOriginType, SCThingType, SCUserConfiguration} from '@openstapps/core';
import {from, of, Observable} from 'rxjs';
import {AuthHelperService} from '../auth/auth-helper.service';
import {mergeMap, concatWith, filter, map, startWith, catchError, tap} from 'rxjs/operators';
import {ConfigProvider} from '../config/config.provider';
import {HttpClient} from '@angular/common/http';
import {EncryptedStorageProvider} from '../storage/encrypted-storage.provider';
@Injectable({providedIn: 'root'})
export class IdCardsProvider {
constructor(
private authHelper: AuthHelperService,
private config: ConfigProvider,
private httpClient: HttpClient,
private encryptedStorageProvider: EncryptedStorageProvider,
) {}
getIdCards(): Observable<SCIdCard[]> {
const feature = this.config.config.app.features.extern?.['idCards'];
const auth = this.authHelper.getProvider(feature?.authProvider ?? 'default');
const storedIdCards = from(
this.encryptedStorageProvider.get<SCIdCard[]>('id-cards') as Promise<SCIdCard[]>,
).pipe(filter(it => it !== undefined));
return auth.isAuthenticated$.pipe(
mergeMap(isAuthenticated =>
isAuthenticated
? feature
? storedIdCards.pipe(
concatWith(
from(auth.getValidToken()).pipe(
mergeMap(token => this.fetchIdCards(feature.url, token.accessToken)),
catchError(() => storedIdCards),
),
),
)
: auth.user$.pipe(
filter(user => user !== undefined),
map(userInfo => this.authHelper.getUserFromUserInfo(userInfo as object)),
mergeMap(user => this.fetchFallbackIdCards(user)),
startWith([]),
)
: of([]).pipe(tap({next: () => this.encryptedStorageProvider.delete('id-cards')})),
),
);
}
private fetchIdCards(url: string, token: string): Observable<SCIdCard[]> {
return this.httpClient
.get<SCIdCard[]>(url, {
headers: {
Authorization: `Bearer ${token}`,
},
responseType: 'json',
})
.pipe(tap({next: idCards => this.encryptedStorageProvider.set('id-cards', idCards)}));
}
private fetchFallbackIdCards(user: SCUserConfiguration): Observable<SCIdCard[]> {
return this.httpClient.get('/assets/examples/student-id.sample.svg', {responseType: 'text'}).pipe(
map(svg => {
let result = svg;
for (const key in user) {
result = result.replaceAll(`{{${key}}}`, (user as unknown as Record<string, string>)[key]);
}
return `data:image/svg+xml;utf8,${encodeURIComponent(result)}`;
}),
map(image => [
{
name: 'Student ID',
image,
type: SCThingType.IdCard,
uid: '1234',
origin: {
name: 'Sample Origin',
type: SCThingOriginType.Remote,
indexed: new Date().toISOString(),
},
},
]),
);
}
}