UNPKG

ng-smart-on-fhir

Version:

[![SRDC](https://www.srdc.com.tr/wp-content/uploads/2014/12/srdc-wp.png)](https://srdc.com.tr/en)

155 lines 14.7 kB
import { Component } from '@angular/core'; import * as jose from 'jose'; import * as i0 from "@angular/core"; import * as i1 from "@angular/router"; import * as i2 from "../../services/smart-auth.service"; import * as i3 from "../../services/shl.service"; import * as i4 from "../../services/smart-on-fhir.service"; import * as i5 from "@angular/common"; import * as i6 from "../../pipes/camel-case-spaced.pipe"; /** * Component for searching and validating Smart Health Cards or Smart Health Links */ export class ShcShlHandlerComponent { get patientName() { return this.patient?.name?.map(name => (name.given?.join(' ') || '') + ' ' + name.family).join(', '); } get patientAge() { if (this.patient?.birthDate) { return Math.ceil((Date.now() - new Date(this.patient.birthDate).getTime()) / (1000 * 3600 * 24 * 365)); } else { return ''; } } constructor(route, auth, shl, sof) { this.route = route; this.auth = auth; this.shl = shl; this.sof = sof; this._window = window; this.invalidSignature = false; this.auth.getPatient().then(patient => this.patient = patient); route.fragment.subscribe(async (fragment) => { try { if (fragment?.startsWith('shlink:/')) { this.sof.importSHCData(await this.shl.handleShl(fragment)); } else if (fragment?.startsWith('shc:/')) { this.sof.importSHCData(await this.shl.handleShc(fragment)); } else { console.log(fragment); } } catch (error) { if (error instanceof jose.errors.JWSSignatureVerificationFailed) { this.invalidSignature = true; } } }); } ngOnInit() { } logout() { this.sof.logout(); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ShcShlHandlerComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.SmartAuthService }, { token: i3.ShlService }, { token: i4.SmartOnFhirService }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: ShcShlHandlerComponent, selector: "sof-shc-shl-handler", ngImport: i0, template: ` <div class="container"> @if (invalidSignature) { <div class="sof-alert sof-alert-danger"> Issuer verification failed for the Smart Health Card! </div> <button class="sof-button sof-button-danger" (click)="logout()"><i class="sof-icon sof-icon-caret-left"></i> Back</button> <button class="sof-button sof-button-warning sof-ml-1 sof-mt-1" (click)="invalidSignature = false"><i class="sof-icon sof-icon-exclamation"></i> Ignore and Continue</button> } @else { <table class="sof-table" id="shc-content"> <tbody> <tr> <td><b>Patient</b></td> <td>{{ patientName }}</td> </tr> <tr> <td><b>Age</b></td> <td>{{ patientAge }}</td> </tr> <tr> <td><b>Gender</b></td> <td>{{ patient?.gender }}</td> </tr> @for (resources of sof.importedResources | keyvalue; track resources.key) { <tr> <td><b>{{resources.key | camelCaseSpaced}}</b></td> <td><span class="sof-badge sof-primary-background sof-text-light">{{resources.value?.length}}</span></td> </tr> } <tr> <td colspan="2" class="text-end"> <button class="sof-button sof-button-primary" routerLink="/">Continue <i class="sof-icon sof-icon-caret-right"></i></button> </td> </tr> </tbody> </table> } </div> <style> #shc-content td:first-child { width: 25em; max-width: 100%; } </style> `, isInline: true, styles: ["\n #shc-content td:first-child {\n width: 25em;\n max-width: 100%;\n }\n "], dependencies: [{ kind: "directive", type: i1.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "pipe", type: i5.KeyValuePipe, name: "keyvalue" }, { kind: "pipe", type: i6.CamelCaseSpacedPipe, name: "camelCaseSpaced" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: ShcShlHandlerComponent, decorators: [{ type: Component, args: [{ selector: 'sof-shc-shl-handler', template: ` <div class="container"> @if (invalidSignature) { <div class="sof-alert sof-alert-danger"> Issuer verification failed for the Smart Health Card! </div> <button class="sof-button sof-button-danger" (click)="logout()"><i class="sof-icon sof-icon-caret-left"></i> Back</button> <button class="sof-button sof-button-warning sof-ml-1 sof-mt-1" (click)="invalidSignature = false"><i class="sof-icon sof-icon-exclamation"></i> Ignore and Continue</button> } @else { <table class="sof-table" id="shc-content"> <tbody> <tr> <td><b>Patient</b></td> <td>{{ patientName }}</td> </tr> <tr> <td><b>Age</b></td> <td>{{ patientAge }}</td> </tr> <tr> <td><b>Gender</b></td> <td>{{ patient?.gender }}</td> </tr> @for (resources of sof.importedResources | keyvalue; track resources.key) { <tr> <td><b>{{resources.key | camelCaseSpaced}}</b></td> <td><span class="sof-badge sof-primary-background sof-text-light">{{resources.value?.length}}</span></td> </tr> } <tr> <td colspan="2" class="text-end"> <button class="sof-button sof-button-primary" routerLink="/">Continue <i class="sof-icon sof-icon-caret-right"></i></button> </td> </tr> </tbody> </table> } </div> <style> #shc-content td:first-child { width: 25em; max-width: 100%; } </style> ` }] }], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i2.SmartAuthService }, { type: i3.ShlService }, { type: i4.SmartOnFhirService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hjLXNobC1oYW5kbGVyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NtYXJ0LW9uLWZoaXIvc3JjL2xpYi9jb21wb25lbnRzL3NoYy1zaGwtaGFuZGxlci9zaGMtc2hsLWhhbmRsZXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQVMsTUFBTSxlQUFlLENBQUM7QUFHaEQsT0FBTyxLQUFLLElBQUksTUFBTSxNQUFNLENBQUM7Ozs7Ozs7O0FBSTdCOztHQUVHO0FBa0RILE1BQU0sT0FBTyxzQkFBc0I7SUFPakMsSUFBSSxXQUFXO1FBQ2IsT0FBTyxJQUFJLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxHQUFHLEdBQUcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO0lBQ3RHLENBQUM7SUFFRCxJQUFJLFVBQVU7UUFDWixJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLENBQUM7WUFDNUIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksR0FBRyxJQUFJLEdBQUcsRUFBRSxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUE7UUFDeEcsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUM7SUFDSCxDQUFDO0lBRUQsWUFBb0IsS0FBcUIsRUFBVSxJQUFzQixFQUFVLEdBQWUsRUFBUyxHQUF1QjtRQUE5RyxVQUFLLEdBQUwsS0FBSyxDQUFnQjtRQUFVLFNBQUksR0FBSixJQUFJLENBQWtCO1FBQVUsUUFBRyxHQUFILEdBQUcsQ0FBWTtRQUFTLFFBQUcsR0FBSCxHQUFHLENBQW9CO1FBbEJsSSxZQUFPLEdBQUcsTUFBTSxDQUFDO1FBRWpCLHFCQUFnQixHQUFZLEtBQUssQ0FBQztRQWlCaEMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxDQUFDO1FBQy9ELEtBQUssQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBQyxRQUFRLEVBQUMsRUFBRTtZQUN4QyxJQUFJLENBQUM7Z0JBQ0gsSUFBSSxRQUFRLEVBQUUsVUFBVSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7b0JBQ3JDLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLE1BQU0sSUFBSSxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQTtnQkFDNUQsQ0FBQztxQkFBTSxJQUFJLFFBQVEsRUFBRSxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztvQkFDekMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFBO2dCQUM1RCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQTtnQkFDdkIsQ0FBQztZQUNILENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLElBQUksS0FBSyxZQUFZLElBQUksQ0FBQyxNQUFNLENBQUMsOEJBQThCLEVBQUUsQ0FBQztvQkFDaEUsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztnQkFDL0IsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFRCxRQUFRO0lBQ1IsQ0FBQztJQUVELE1BQU07UUFDSixJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ3BCLENBQUM7K0dBM0NVLHNCQUFzQjttR0FBdEIsc0JBQXNCLDJEQS9DdkI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNENUOzs0RkFHVSxzQkFBc0I7a0JBakRsQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxxQkFBcUI7b0JBQy9CLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E0Q1Q7aUJBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0NvbXBvbmVudCwgT25Jbml0fSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtBY3RpdmF0ZWRSb3V0ZX0gZnJvbSBcIkBhbmd1bGFyL3JvdXRlclwiO1xyXG5pbXBvcnQge1NobFNlcnZpY2V9IGZyb20gXCIuLi8uLi9zZXJ2aWNlcy9zaGwuc2VydmljZVwiO1xyXG5pbXBvcnQgKiBhcyBqb3NlIGZyb20gJ2pvc2UnO1xyXG5pbXBvcnQge1NtYXJ0T25GaGlyU2VydmljZX0gZnJvbSBcIi4uLy4uL3NlcnZpY2VzL3NtYXJ0LW9uLWZoaXIuc2VydmljZVwiO1xyXG5pbXBvcnQge1NtYXJ0QXV0aFNlcnZpY2V9IGZyb20gXCIuLi8uLi9zZXJ2aWNlcy9zbWFydC1hdXRoLnNlcnZpY2VcIjtcclxuXHJcbi8qKlxyXG4gKiBDb21wb25lbnQgZm9yIHNlYXJjaGluZyBhbmQgdmFsaWRhdGluZyBTbWFydCBIZWFsdGggQ2FyZHMgb3IgU21hcnQgSGVhbHRoIExpbmtzXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ3NvZi1zaGMtc2hsLWhhbmRsZXInLFxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8ZGl2IGNsYXNzPVwiY29udGFpbmVyXCI+XHJcbiAgICAgIEBpZiAoaW52YWxpZFNpZ25hdHVyZSkge1xyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJzb2YtYWxlcnQgc29mLWFsZXJ0LWRhbmdlclwiPlxyXG4gICAgICAgICAgSXNzdWVyIHZlcmlmaWNhdGlvbiBmYWlsZWQgZm9yIHRoZSBTbWFydCBIZWFsdGggQ2FyZCFcclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8YnV0dG9uIGNsYXNzPVwic29mLWJ1dHRvbiBzb2YtYnV0dG9uLWRhbmdlclwiIChjbGljayk9XCJsb2dvdXQoKVwiPjxpIGNsYXNzPVwic29mLWljb24gc29mLWljb24tY2FyZXQtbGVmdFwiPjwvaT4gQmFjazwvYnV0dG9uPlxyXG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJzb2YtYnV0dG9uIHNvZi1idXR0b24td2FybmluZyBzb2YtbWwtMSBzb2YtbXQtMVwiIChjbGljayk9XCJpbnZhbGlkU2lnbmF0dXJlID0gZmFsc2VcIj48aSBjbGFzcz1cInNvZi1pY29uIHNvZi1pY29uLWV4Y2xhbWF0aW9uXCI+PC9pPiBJZ25vcmUgYW5kIENvbnRpbnVlPC9idXR0b24+XHJcbiAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgIDx0YWJsZSBjbGFzcz1cInNvZi10YWJsZVwiIGlkPVwic2hjLWNvbnRlbnRcIj5cclxuICAgICAgICAgIDx0Ym9keT5cclxuICAgICAgICAgIDx0cj5cclxuICAgICAgICAgICAgPHRkPjxiPlBhdGllbnQ8L2I+PC90ZD5cclxuICAgICAgICAgICAgPHRkPnt7IHBhdGllbnROYW1lIH19PC90ZD5cclxuICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICA8dHI+XHJcbiAgICAgICAgICAgIDx0ZD48Yj5BZ2U8L2I+PC90ZD5cclxuICAgICAgICAgICAgPHRkPnt7IHBhdGllbnRBZ2UgfX08L3RkPlxyXG4gICAgICAgICAgPC90cj5cclxuICAgICAgICAgIDx0cj5cclxuICAgICAgICAgICAgPHRkPjxiPkdlbmRlcjwvYj48L3RkPlxyXG4gICAgICAgICAgICA8dGQ+e3sgcGF0aWVudD8uZ2VuZGVyIH19PC90ZD5cclxuICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgIEBmb3IgKHJlc291cmNlcyBvZiBzb2YuaW1wb3J0ZWRSZXNvdXJjZXMgfCBrZXl2YWx1ZTsgdHJhY2sgcmVzb3VyY2VzLmtleSkge1xyXG4gICAgICAgICAgICAgIDx0cj5cclxuICAgICAgICAgICAgICAgIDx0ZD48Yj57e3Jlc291cmNlcy5rZXkgfCBjYW1lbENhc2VTcGFjZWR9fTwvYj48L3RkPlxyXG4gICAgICAgICAgICAgICAgPHRkPjxzcGFuIGNsYXNzPVwic29mLWJhZGdlIHNvZi1wcmltYXJ5LWJhY2tncm91bmQgc29mLXRleHQtbGlnaHRcIj57e3Jlc291cmNlcy52YWx1ZT8ubGVuZ3RofX08L3NwYW4+PC90ZD5cclxuICAgICAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICA8dHI+XHJcbiAgICAgICAgICAgIDx0ZCBjb2xzcGFuPVwiMlwiIGNsYXNzPVwidGV4dC1lbmRcIj5cclxuICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwic29mLWJ1dHRvbiBzb2YtYnV0dG9uLXByaW1hcnlcIiByb3V0ZXJMaW5rPVwiL1wiPkNvbnRpbnVlIDxpIGNsYXNzPVwic29mLWljb24gc29mLWljb24tY2FyZXQtcmlnaHRcIj48L2k+PC9idXR0b24+XHJcbiAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICA8L3RyPlxyXG4gICAgICAgICAgPC90Ym9keT5cclxuICAgICAgICA8L3RhYmxlPlxyXG4gICAgICB9XHJcbiAgICA8L2Rpdj5cclxuICAgIDxzdHlsZT5cclxuICAgICAgI3NoYy1jb250ZW50IHRkOmZpcnN0LWNoaWxkIHtcclxuICAgICAgICB3aWR0aDogMjVlbTtcclxuICAgICAgICBtYXgtd2lkdGg6IDEwMCU7XHJcbiAgICAgIH1cclxuICAgIDwvc3R5bGU+XHJcbiAgYFxyXG59KVxyXG5cclxuZXhwb3J0IGNsYXNzIFNoY1NobEhhbmRsZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gIF93aW5kb3cgPSB3aW5kb3c7XHJcblxyXG4gIGludmFsaWRTaWduYXR1cmU6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgcGF0aWVudDogZmhpcjQuUGF0aWVudHx1bmRlZmluZWQ7XHJcblxyXG4gIGdldCBwYXRpZW50TmFtZSgpIHtcclxuICAgIHJldHVybiB0aGlzLnBhdGllbnQ/Lm5hbWU/Lm1hcChuYW1lID0+IChuYW1lLmdpdmVuPy5qb2luKCcgJykgfHwgJycpICsgJyAnICsgbmFtZS5mYW1pbHkpLmpvaW4oJywgJylcclxuICB9XHJcblxyXG4gIGdldCBwYXRpZW50QWdlKCkge1xyXG4gICAgaWYgKHRoaXMucGF0aWVudD8uYmlydGhEYXRlKSB7XHJcbiAgICAgIHJldHVybiBNYXRoLmNlaWwoKERhdGUubm93KCkgLSBuZXcgRGF0ZSh0aGlzLnBhdGllbnQuYmlydGhEYXRlKS5nZXRUaW1lKCkpIC8gKDEwMDAgKiAzNjAwICogMjQgKiAzNjUpKVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuICcnO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsIHByaXZhdGUgYXV0aDogU21hcnRBdXRoU2VydmljZSwgcHJpdmF0ZSBzaGw6IFNobFNlcnZpY2UsIHB1YmxpYyBzb2Y6IFNtYXJ0T25GaGlyU2VydmljZSkge1xyXG4gICAgdGhpcy5hdXRoLmdldFBhdGllbnQoKS50aGVuKHBhdGllbnQgPT4gdGhpcy5wYXRpZW50ID0gcGF0aWVudCk7XHJcbiAgICByb3V0ZS5mcmFnbWVudC5zdWJzY3JpYmUoYXN5bmMgZnJhZ21lbnQgPT4ge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGlmIChmcmFnbWVudD8uc3RhcnRzV2l0aCgnc2hsaW5rOi8nKSkge1xyXG4gICAgICAgICAgdGhpcy5zb2YuaW1wb3J0U0hDRGF0YShhd2FpdCB0aGlzLnNobC5oYW5kbGVTaGwoZnJhZ21lbnQpKVxyXG4gICAgICAgIH0gZWxzZSBpZiAoZnJhZ21lbnQ/LnN0YXJ0c1dpdGgoJ3NoYzovJykpIHtcclxuICAgICAgICAgIHRoaXMuc29mLmltcG9ydFNIQ0RhdGEoYXdhaXQgdGhpcy5zaGwuaGFuZGxlU2hjKGZyYWdtZW50KSlcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgY29uc29sZS5sb2coZnJhZ21lbnQpXHJcbiAgICAgICAgfVxyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIGpvc2UuZXJyb3JzLkpXU1NpZ25hdHVyZVZlcmlmaWNhdGlvbkZhaWxlZCkge1xyXG4gICAgICAgICAgdGhpcy5pbnZhbGlkU2lnbmF0dXJlID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pXHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICB9XHJcblxyXG4gIGxvZ291dCgpIHtcclxuICAgIHRoaXMuc29mLmxvZ291dCgpO1xyXG4gIH1cclxufVxyXG4iXX0=