ssi-security-commons 0.16.17 → 0.16.19

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.
@@ -10,7 +10,7 @@ import { MatButtonModule } from '@angular/material/button';
10
10
  import * as i1$1 from '@angular/common/http';
11
11
  import { HttpHeaders, HttpResponse, HttpErrorResponse } from '@angular/common/http';
12
12
  import { map, catchError, switchMap, filter, take } from 'rxjs/operators';
13
- import { BehaviorSubject, throwError } from 'rxjs';
13
+ import { BehaviorSubject, throwError, map as map$1 } from 'rxjs';
14
14
  import * as i2$2 from '@angular/router';
15
15
 
16
16
  class SsiSecurityCommonsService {
@@ -289,6 +289,11 @@ class SessionService {
289
289
  data = window.localStorage.getItem(u);
290
290
  token = window.localStorage.getItem(t);
291
291
  refreshToken = window.localStorage.getItem(r);
292
+ if (data && token && refreshToken) {
293
+ data = this.cryptoService.decrypt(data);
294
+ token = this.cryptoService.decrypt(token);
295
+ refreshToken = this.cryptoService.decrypt(refreshToken);
296
+ }
292
297
  }
293
298
  else {
294
299
  data = window.localStorage.getItem(USERDATA);
@@ -935,6 +940,249 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.3", ngImpor
935
940
  type: Injectable
936
941
  }], ctorParameters: function () { return [{ type: i0.Injector }, { type: i2$2.Router }, { type: CryptoService }, { type: JwtService }, { type: SessionService }]; } });
937
942
 
943
+ /* eslint-disable max-lines-per-function */
944
+ /* eslint-disable prefer-const */
945
+ class WebAuthnService {
946
+ constructor(sessionService, http, snackBar, environment) {
947
+ this.sessionService = sessionService;
948
+ this.http = http;
949
+ this.snackBar = snackBar;
950
+ this.webAuthnAvailable = !!navigator.credentials && !!navigator.credentials.create;
951
+ this.environment = environment;
952
+ }
953
+ webAuthnSignup(user) {
954
+ console.log('[webAuthnSignup]');
955
+ const publicKeyCredentialCreationOptions = {
956
+ challenge: this.getChallenge(),
957
+ rp: {
958
+ name: 'WebAuthn',
959
+ },
960
+ user: {
961
+ id: Uint8Array.from(user.id, c => c.charCodeAt(0)),
962
+ name: user.email,
963
+ displayName: user.email,
964
+ },
965
+ pubKeyCredParams: [{ alg: -7, type: 'public-key' }],
966
+ authenticatorSelection: {
967
+ authenticatorAttachment: 'platform',
968
+ },
969
+ timeout: 60000,
970
+ attestation: 'direct'
971
+ };
972
+ return navigator.credentials.create({
973
+ publicKey: publicKeyCredentialCreationOptions,
974
+ });
975
+ }
976
+ webAuthnSignin(user) {
977
+ console.log(user);
978
+ /* {
979
+ "id": "b18ee077-f896-44f4-a2d4-3ac831eb1c90",
980
+ "email": "test.user@email.com",
981
+ "password": "",
982
+ "credentials": [
983
+ [
984
+ {
985
+ "id": {},
986
+ "type": "public-key"
987
+ }
988
+ ]
989
+ ]
990
+ } */
991
+ let publicKeyCredentials = {
992
+ challenge: this.getChallenge(),
993
+ allowCredentials: user.credentials[0]
994
+ };
995
+ return navigator.credentials.get({ publicKey: publicKeyCredentials });
996
+ }
997
+ getChallenge() {
998
+ return Uint8Array.from('jEfcn1CsGFxBiXYtJMSGDycPqPoyFJ3Z', c => c.charCodeAt(0));
999
+ }
1000
+ register(user, newCredentialInfo) {
1001
+ const promise = new Promise((resolve, reject) => {
1002
+ let enc = new TextDecoder('utf-8');
1003
+ let clientDataJSON = enc.decode(newCredentialInfo.response.clientDataJSON);
1004
+ console.log(clientDataJSON);
1005
+ let clientData = JSON.parse(clientDataJSON);
1006
+ console.log(clientData);
1007
+ const publicKey = this.arrayBufferToBase64Url(newCredentialInfo.rawId);
1008
+ let idList = [{
1009
+ // id: newCredentialInfo.rawId,
1010
+ id: publicKey,
1011
+ type: 'public-key'
1012
+ }];
1013
+ user.credentials.push(idList);
1014
+ console.log(user);
1015
+ this.addAttributeUser(user.id, 'webauthn_key', publicKey).subscribe({
1016
+ next: (res) => {
1017
+ console.log(res);
1018
+ resolve(res);
1019
+ },
1020
+ error: (err) => {
1021
+ console.error(err);
1022
+ reject(err);
1023
+ }
1024
+ });
1025
+ });
1026
+ return promise;
1027
+ }
1028
+ base64UrlToArrayBuffer(base64UrlString) {
1029
+ const base64String = base64UrlString.replace(/-/g, '+').replace(/_/g, '/');
1030
+ const paddedBase64String = base64String.padEnd(Math.ceil(base64String.length / 4) * 4, '=');
1031
+ const uint8Array = new Uint8Array(atob(paddedBase64String)
1032
+ .split('')
1033
+ .map((char) => char.charCodeAt(0)));
1034
+ return uint8Array.buffer;
1035
+ }
1036
+ arrayBufferToBase64Url(arrayBuffer) {
1037
+ const uint8Array = new Uint8Array(arrayBuffer);
1038
+ let base64String = btoa(String.fromCharCode.apply(null, Array.from(uint8Array)));
1039
+ base64String = base64String.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
1040
+ return base64String;
1041
+ }
1042
+ signUp() {
1043
+ const promise = new Promise((resolve, reject) => {
1044
+ if (this.webAuthnAvailable) {
1045
+ const userData = this.sessionService.getUserdata();
1046
+ if (userData) {
1047
+ let user = {
1048
+ id: userData?.userId,
1049
+ email: userData?.email,
1050
+ credentials: []
1051
+ };
1052
+ this.webAuthnSignup(user)
1053
+ .then((credential) => {
1054
+ console.log('credentials.create RESPONSE', credential);
1055
+ this.register(user, credential).then((res) => {
1056
+ console.log(res);
1057
+ this.showSnackBar(this.getMessage('signUpOk'), ['snack-success']);
1058
+ resolve(this.getMessage('signUpOk'));
1059
+ }).catch((err) => {
1060
+ console.error(err);
1061
+ this.showSnackBar(this.getMessage('signUpNok'), ['snack-error']);
1062
+ reject(this.getMessage('signUpNok'));
1063
+ });
1064
+ }).catch((error) => {
1065
+ console.error('credentials.create ERROR', error);
1066
+ this.showSnackBar(this.getMessage('signUpNok'), ['snack-error']);
1067
+ reject(this.getMessage('signUpNok'));
1068
+ });
1069
+ }
1070
+ }
1071
+ else {
1072
+ this.showSnackBar(this.getMessage('browserNok'), ['snack-error']);
1073
+ reject(this.getMessage('browserNok'));
1074
+ }
1075
+ });
1076
+ return promise;
1077
+ }
1078
+ signIn() {
1079
+ const promise = new Promise((resolve, reject) => {
1080
+ if (this.webAuthnAvailable) {
1081
+ const userData = this.sessionService.getUserdata();
1082
+ if (userData) {
1083
+ let user = {
1084
+ id: userData?.userId,
1085
+ email: userData?.email,
1086
+ credentials: [{}]
1087
+ };
1088
+ this.getAttributeUser(user.id, 'webauthn_key').subscribe({
1089
+ next: (res) => {
1090
+ console.log(res);
1091
+ if (res.data && res.data.webauthn_key && res.data.webauthn_key.length > 0) {
1092
+ const cred = {
1093
+ id: this.base64UrlToArrayBuffer(res.data.webauthn_key[0]),
1094
+ type: 'public-key'
1095
+ };
1096
+ user.credentials.splice(0, 1);
1097
+ user.credentials.push([cred]);
1098
+ this.webAuthnSignin(user).then((response) => {
1099
+ console.log('SUCCESSFULLY GOT AN ASSERTION!', response);
1100
+ resolve('ok');
1101
+ })
1102
+ .catch((error) => {
1103
+ console.error('FAIL', error);
1104
+ this.showSnackBar(this.getMessage('invalidCredentials'), ['snack-error']);
1105
+ reject(this.getMessage('invalidCredentials'));
1106
+ });
1107
+ }
1108
+ else {
1109
+ this.showSnackBar(this.getMessage('noCredentials'), ['snack-error']);
1110
+ reject(this.getMessage('noCredentials'));
1111
+ }
1112
+ },
1113
+ error: (err) => {
1114
+ console.error(err);
1115
+ this.showSnackBar(this.getMessage('errorRetrievingCredentials'), ['snack-error']);
1116
+ reject(this.getMessage('errorRetrievingCredentials'));
1117
+ }
1118
+ });
1119
+ }
1120
+ }
1121
+ else {
1122
+ this.showSnackBar(this.getMessage('browserNok'), ['snack-error']);
1123
+ reject(this.getMessage('browserNok'));
1124
+ }
1125
+ });
1126
+ return promise;
1127
+ }
1128
+ addAttributeUser(userId, code, value) {
1129
+ return this.http.post(this.environment.endPoint + `/user/attribute/value/${userId}/${code}/${value}`, {})
1130
+ .pipe(map$1(res => res));
1131
+ }
1132
+ getAttributeUser(userId, code) {
1133
+ return this.http.get(this.environment.endPoint + `/user/attribute/value/${userId}/${code}`)
1134
+ .pipe(map$1(res => res));
1135
+ }
1136
+ showSnackBar(message, panelClass = []) {
1137
+ console.log(message);
1138
+ setTimeout(() => {
1139
+ this.snackBar.open(message, undefined, {
1140
+ duration: 5000,
1141
+ panelClass,
1142
+ verticalPosition: 'top'
1143
+ });
1144
+ });
1145
+ }
1146
+ getMessage(code) {
1147
+ let msg = '';
1148
+ const lang = window.localStorage.getItem('LANG');
1149
+ const messagesEn = {
1150
+ signUpOk: 'Credentials registered successfully',
1151
+ signUpNok: 'A problem occurred while registering credentials',
1152
+ browserNok: 'The browser does not support this functionality',
1153
+ noCredentials: 'The user has no stored credentials',
1154
+ invalidCredentials: 'The credentials are invalid',
1155
+ errorRetrievingCredentials: 'There was a problem retrieving credentials',
1156
+ };
1157
+ const messagesEs = {
1158
+ signUpOk: 'Credenciales registradas exitosamente',
1159
+ signUpNok: 'Se produjo un problema al registrar las credenciales',
1160
+ browserNok: 'El navegador no soporta esta funcionalidad',
1161
+ noCredentials: 'El usuario no tiene credenciales almacenadas',
1162
+ invalidCredentials: 'Las credenciales no son válidas',
1163
+ errorRetrievingCredentials: 'Se produjo un problema al recuperar las credenciales',
1164
+ };
1165
+ if (lang && lang === 'en') {
1166
+ msg = messagesEn[code];
1167
+ }
1168
+ else {
1169
+ msg = messagesEs[code];
1170
+ }
1171
+ return msg;
1172
+ }
1173
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: WebAuthnService, deps: [{ token: SessionService }, { token: i1$1.HttpClient }, { token: i2$1.MatSnackBar }, { token: 'environment' }], target: i0.ɵɵFactoryTarget.Injectable }); }
1174
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: WebAuthnService, providedIn: 'root' }); }
1175
+ }
1176
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.3", ngImport: i0, type: WebAuthnService, decorators: [{
1177
+ type: Injectable,
1178
+ args: [{
1179
+ providedIn: 'root'
1180
+ }]
1181
+ }], ctorParameters: function () { return [{ type: SessionService }, { type: i1$1.HttpClient }, { type: i2$1.MatSnackBar }, { type: undefined, decorators: [{
1182
+ type: Inject,
1183
+ args: ['environment']
1184
+ }] }]; } });
1185
+
938
1186
  /*
939
1187
  * Public API Surface of ssi-security-commons
940
1188
  */
@@ -943,5 +1191,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.0.3", ngImpor
943
1191
  * Generated bundle index. Do not edit.
944
1192
  */
945
1193
 
946
- export { AuthInterceptor, CryptoService, JwtService, LANG, MessagesService, REFRESH_TOKEN, ResponseInterceptor, SessionService, SsiSecurityCommonsComponent, SsiSecurityCommonsModule, SsiSecurityCommonsService, TOKEN, USERDATA };
1194
+ export { AuthInterceptor, CryptoService, JwtService, LANG, MessagesService, REFRESH_TOKEN, ResponseInterceptor, SessionService, SsiSecurityCommonsComponent, SsiSecurityCommonsModule, SsiSecurityCommonsService, TOKEN, USERDATA, WebAuthnService };
947
1195
  //# sourceMappingURL=ssi-security-commons.mjs.map