ssi-security-commons 0.16.27 → 0.16.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -11,9 +11,9 @@ import * as i3 from '@angular/common';
11
11
  import { CommonModule } from '@angular/common';
12
12
  import * as i1$1 from '@angular/common/http';
13
13
  import { HttpHeaders, HttpResponse, HttpErrorResponse } from '@angular/common/http';
14
- import { map, catchError, switchMap, filter, take } from 'rxjs/operators';
15
- import { BehaviorSubject, throwError, map as map$1 } from 'rxjs';
16
- import * as i2$2 from '@angular/router';
14
+ import { map, switchMap, catchError, filter, take } from 'rxjs/operators';
15
+ import { from, BehaviorSubject, throwError, map as map$1 } from 'rxjs';
16
+ import * as i3$1 from '@angular/router';
17
17
 
18
18
  class SsiSecurityCommonsService {
19
19
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: SsiSecurityCommonsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
@@ -167,7 +167,8 @@ class SessionService {
167
167
  username: tokenData.preferred_username,
168
168
  email: tokenData.email,
169
169
  emailVerified: tokenData.email_verified,
170
- countryCode: tokenData.country_code
170
+ countryCode: tokenData.country_code,
171
+ partyId: tokenData.party_id
171
172
  };
172
173
  return userData;
173
174
  }
@@ -894,10 +895,79 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.3", ngImpor
894
895
  }]
895
896
  }] });
896
897
 
898
+ class HybridEncryptionService {
899
+ constructor() {
900
+ this.publicKeyPem = `-----BEGIN PUBLIC KEY-----
901
+ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAydjMaPDQvcNCPsB3zmuA
902
+ RyDw/eVPjH8eITcWq+TnmqW4FCxwTxAQQy8bEnO7HC8eUVaD8tlNaLVjiRRCo0+o
903
+ JMDZC5S9aUGpz/Ueghp5aziu0abk7pZ+x/BrfpAN+7VteZh00d/YAtZlbQ6kHM44
904
+ oz2d7Fj1MPzB22ZoEnmcFqBlvsW8yblM38HEAKRXj9733XiayDoq6ivP046IFBpP
905
+ Cgg7kOLfOYMt7ZNkaKzDeYBfQAvhW+Nd6EN+8CCrI8//fnwRbrItzgR5KXwJ0F5T
906
+ w6/YhIkJi7Ce6kR8D7aYdXNoRKzX5m+GxSkLtiMImHOnVWg+wo/lvCbLRWS+QQ14
907
+ pQIDAQAB
908
+ -----END PUBLIC KEY-----`;
909
+ this.loadPublicKey();
910
+ }
911
+ /** Import RSA public key */
912
+ async loadPublicKey() {
913
+ const pemHeader = '-----BEGIN PUBLIC KEY-----';
914
+ const pemFooter = '-----END PUBLIC KEY-----';
915
+ const pemContents = this.publicKeyPem
916
+ .replace(pemHeader, '')
917
+ .replace(pemFooter, '')
918
+ .replace(/\s/g, '');
919
+ const binaryDer = Uint8Array.from(atob(pemContents), c => c.charCodeAt(0));
920
+ this.publicKey = await crypto.subtle.importKey('spki', binaryDer.buffer, {
921
+ name: 'RSA-OAEP',
922
+ hash: 'SHA-256'
923
+ }, true, ['encrypt']);
924
+ }
925
+ /** Generate a random AES key */
926
+ async generateAesKey() {
927
+ return crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);
928
+ }
929
+ /** Encrypt large data with AES and AES key with RSA */
930
+ async encrypt(data) {
931
+ if (!this.publicKey) {
932
+ await this.loadPublicKey();
933
+ }
934
+ // Convert payload to JSON + Uint8Array
935
+ const encoder = new TextEncoder();
936
+ const plainBytes = encoder.encode(JSON.stringify(data));
937
+ // Generate AES key + IV
938
+ const aesKey = await this.generateAesKey();
939
+ const iv = crypto.getRandomValues(new Uint8Array(12)); // AES-GCM nonce
940
+ // Encrypt data with AES
941
+ const encryptedDataBuffer = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, aesKey, plainBytes);
942
+ // Export AES key
943
+ const rawAesKey = await crypto.subtle.exportKey('raw', aesKey);
944
+ // Encrypt AES key with RSA
945
+ const encryptedKeyBuffer = await crypto.subtle.encrypt({ name: 'RSA-OAEP' }, this.publicKey, rawAesKey);
946
+ return {
947
+ encryptedKey: this.arrayBufferToBase64(encryptedKeyBuffer),
948
+ encryptedData: this.arrayBufferToBase64(encryptedDataBuffer),
949
+ iv: this.arrayBufferToBase64(iv.buffer)
950
+ };
951
+ }
952
+ /** Convert ArrayBuffer → Base64 */
953
+ arrayBufferToBase64(buffer) {
954
+ return btoa(String.fromCharCode(...new Uint8Array(buffer)));
955
+ }
956
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: HybridEncryptionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
957
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: HybridEncryptionService, providedIn: 'root' }); }
958
+ }
959
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: HybridEncryptionService, decorators: [{
960
+ type: Injectable,
961
+ args: [{
962
+ providedIn: 'root'
963
+ }]
964
+ }], ctorParameters: function () { return []; } });
965
+
897
966
  /* eslint-disable */
898
967
  class AuthInterceptor {
899
- constructor(cryptoService, environment) {
968
+ constructor(cryptoService, hybridEncryptionService, environment) {
900
969
  this.cryptoService = cryptoService;
970
+ this.hybridEncryptionService = hybridEncryptionService;
901
971
  console.log('AuthInterceptor constructor');
902
972
  this.environment = environment;
903
973
  }
@@ -937,14 +1007,23 @@ class AuthInterceptor {
937
1007
  headers: request.headers.append('Language', l)
938
1008
  });
939
1009
  }
1010
+ const isEncrypted = request.headers.get('X-Encrypted');
1011
+ if (isEncrypted === 'true' && request.body) {
1012
+ return from(this.hybridEncryptionService.encrypt(request.body)).pipe(switchMap(encryptedPayload => {
1013
+ const newReq = request.clone({
1014
+ body: encryptedPayload
1015
+ });
1016
+ return next.handle(newReq);
1017
+ }));
1018
+ }
940
1019
  return next.handle(request);
941
1020
  }
942
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: AuthInterceptor, deps: [{ token: CryptoService }, { token: 'environment' }], target: i0.ɵɵFactoryTarget.Injectable }); }
1021
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: AuthInterceptor, deps: [{ token: CryptoService }, { token: HybridEncryptionService }, { token: 'environment' }], target: i0.ɵɵFactoryTarget.Injectable }); }
943
1022
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: AuthInterceptor }); }
944
1023
  }
945
1024
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: AuthInterceptor, decorators: [{
946
1025
  type: Injectable
947
- }], ctorParameters: function () { return [{ type: CryptoService }, { type: undefined, decorators: [{
1026
+ }], ctorParameters: function () { return [{ type: CryptoService }, { type: HybridEncryptionService }, { type: undefined, decorators: [{
948
1027
  type: Inject,
949
1028
  args: ['environment']
950
1029
  }] }]; } });
@@ -1041,12 +1120,12 @@ class ResponseInterceptor {
1041
1120
  console.error(err);
1042
1121
  });
1043
1122
  }
1044
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: ResponseInterceptor, deps: [{ token: i0.Injector }, { token: i2$2.Router }, { token: CryptoService }, { token: JwtService }, { token: SessionService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1123
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: ResponseInterceptor, deps: [{ token: i0.Injector }, { token: i3$1.Router }, { token: CryptoService }, { token: JwtService }, { token: SessionService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1045
1124
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: ResponseInterceptor }); }
1046
1125
  }
1047
1126
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: ResponseInterceptor, decorators: [{
1048
1127
  type: Injectable
1049
- }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i2$2.Router }, { type: CryptoService }, { type: JwtService }, { type: SessionService }]; } });
1128
+ }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i3$1.Router }, { type: CryptoService }, { type: JwtService }, { type: SessionService }]; } });
1050
1129
 
1051
1130
  /* eslint-disable max-lines-per-function */
1052
1131
  /* eslint-disable prefer-const */
@@ -1102,9 +1181,24 @@ class WebAuthnService {
1102
1181
  };
1103
1182
  return navigator.credentials.get({ publicKey: publicKeyCredentials });
1104
1183
  }
1105
- getChallenge() {
1184
+ getChallengeOld() {
1106
1185
  return Uint8Array.from('jEfcn1CsGFxBiXYtJMSGDycPqPoyFJ3Z', c => c.charCodeAt(0));
1107
1186
  }
1187
+ getChallenge() {
1188
+ let base64 = 'jEfcn1CsGFxBiXYtJMSGDycPqPoyFJ3Z'
1189
+ .replace(/-/g, '+')
1190
+ .replace(/_/g, '/');
1191
+ while (base64.length % 4) {
1192
+ base64 += '=';
1193
+ }
1194
+ const binaryString = atob(base64);
1195
+ const len = binaryString.length;
1196
+ const bytes = new Uint8Array(len);
1197
+ for (let i = 0; i < len; i++) {
1198
+ bytes[i] = binaryString.charCodeAt(i);
1199
+ }
1200
+ return bytes;
1201
+ }
1108
1202
  register(user, newCredentialInfo) {
1109
1203
  const promise = new Promise((resolve, reject) => {
1110
1204
  let enc = new TextDecoder('utf-8');