gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[reclaim-ui] 381/459: even more quality of life improvements


From: gnunet
Subject: [reclaim-ui] 381/459: even more quality of life improvements
Date: Fri, 11 Jun 2021 23:27:53 +0200

This is an automated email from the git hooks/post-receive script.

martin-schanzenbach pushed a commit to branch master
in repository reclaim-ui.

commit 3e47b9ccd2749ab48a62f6e1ac4b4938a350a13b
Author: Martin Schanzenbach <schanzen@gnunet.org>
AuthorDate: Sun Dec 27 14:16:56 2020 +0900

    even more quality of life improvements
---
 src/app/config.service.ts                          |   8 +-
 src/app/credential.service.ts                      |   6 +-
 src/app/edit-identity/edit-identity.component.html |  80 +++----
 src/app/edit-identity/edit-identity.component.ts   | 244 ++++++++++++++++++++-
 src/locales/de/messages.json                       |   7 +-
 src/locales/en/messages.json                       |   7 +-
 6 files changed, 298 insertions(+), 54 deletions(-)

diff --git a/src/app/config.service.ts b/src/app/config.service.ts
index b08b9a8..7a10c0e 100644
--- a/src/app/config.service.ts
+++ b/src/app/config.service.ts
@@ -9,18 +9,22 @@ export class ConfigService {
   defaultConfig: Config;
 
   constructor(private http: HttpClient) {
+    this.config = new Config('',true);
     var confString = localStorage.getItem('reclaimSettings');
+    this.config = new Config('',true);
     try {
-      this.config = JSON.parse(confString);
-      if (this.config == null) {
+      var jsonConfig = JSON.parse(confString);
+      if (jsonConfig == null) {
         this.loadDefaults();
       } else {
+        this.config = jsonConfig;
         console.log("Loaded settings: " + confString);
       }
     } catch(e) {
       this.loadDefaults();
       console.log("Error loading settings: " + e);
     }
+
   }
 
   loadDefaults() {
diff --git a/src/app/credential.service.ts b/src/app/credential.service.ts
index 699324f..550f0d3 100644
--- a/src/app/credential.service.ts
+++ b/src/app/credential.service.ts
@@ -23,7 +23,11 @@ export class CredentialService {
         var redirectUri;
         if (window.location.href.includes('localhost')){
             const user = localStorage.getItem('userForCredential');
-            redirectUri = 'http://localhost:4200/import-attributes/' + user;
+            if (window.location.href.includes('import-attributes')){
+              redirectUri = 'http://localhost:4200/import-attributes/' + user;
+            } else {
+              redirectUri = 'http://localhost:4200/edit-identity/' + user;
+            }
         }
         else {
             redirectUri = "https://ui.reclaim";;
diff --git a/src/app/edit-identity/edit-identity.component.html 
b/src/app/edit-identity/edit-identity.component.html
index aa7414c..10d7a68 100644
--- a/src/app/edit-identity/edit-identity.component.html
+++ b/src/app/edit-identity/edit-identity.component.html
@@ -9,36 +9,29 @@
       <h2 class="fa-2x"><i class="fa fa-user-circle pr-2"></i> {{ 
identity.name }}</h2>
     </div>
   </div>
-  <!--IdProvider-Discovery-->
-  <div *ngIf="!hasAttributes()" class="alert alert-primary alert-dismissible 
fade show my-2" role="alert" >
-    <span class="fa fa-info"> </span>  <b 
class="ml-2">{{getMessage("edit_identity_html@noAttributes")}}</b><br/>
-    {{getMessage("edit_identity_html@importInfo")}}<br/>
-    <button class="btn btn-primary" [routerLink]="['/import-attributes', 
identity.name ]">
-      <span class="fa fa-download"></span> 
{{getMessage("edit_identity_html@linkAccount")}}
-    </button>
-  </div>
 
+  <div class="card-body text-center fa-4x" *ngIf="importInProgress">
+    <i class="fa fa-spinner fa-spin"></i>
+    Please wait
+  </div>
   <!-- Attribute table -->
-  <div class="card-body">
+  <div class="card-body" *ngIf="!importInProgress">
     <div>
-      <h3 class="card-subtitle mb-2"> 
{{getMessage("edit_identity_html@basicInfo")}} <span (click)="showGeneralInfo = 
!showGeneralInfo" class="fa fa-question-circle"></span></h3>
+      <h3 class="card-subtitle mb-4"> 
{{getMessage("edit_identity_html@basicInfo")}} <span (click)="showGeneralInfo = 
!showGeneralInfo" class="fa fa-question-circle"></span></h3>
       <div class="alert alert-secondary fade show" *ngIf="showGeneralInfo" >
         {{getMessage("edit_identity_html@standardScopes")}}
       </div>
-
       <div class="table pb-1">
-          <!-- Standard "profile" claims first -->
+          <!-- Standard "email" claims first -->
           <div class="row mb-3" [class.openid]="inOpenIdFlow()"
               [class.text-primary]="isClaimRequested(claim) || claim == 
claimInEdit"
               [class.alert-danger]="newAttribute.name === claim.name"
-              *ngFor="let claim of existingProfileClaims">
+              *ngFor="let claim of existingEmailClaims">
             <div class="col-sm"><div style="min-width: 15em">
-                <i *ngIf="isClaimRequested(claim)" class="fa 
fa-openid"></i><b> {{ getDescription(claim) }}</b>
-              </div>
-            </div>
+                <i *ngIf="isClaimRequested(claim)" class="fa 
fa-openid"></i><b> {{ getDescription(claim) }}</b></div></div>
             <div class="col-sm">
               <input *ngIf="!isClaimCred(claim) && (claim == claimInEdit)" 
placeholder="{{ getMessage('Value') }}" [(ngModel)]="claim.value">
-              <span *ngIf="!isClaimCred(claim) && (claim != claimInEdit)">{{ 
claim.value }} <i class="text-secondary" style="float:right;"><i class="fa 
fa-certificate"></i> Self-issued</i></span>
+              <span *ngIf="!isClaimCred(claim) && (claim != claimInEdit)">{{ 
claim.value }} <i class="text-secondary" style="float:right;"><i class="fa 
fa-certificate"></i> {{ getMessage("edit_identity_html@selfissued") 
}}</i></span>
               <span *ngIf="isClaimCred(claim)"  >{{ getCredValue(claim) }} <i 
class="text-primary" style="float:right;"><i class="fa fa-certificate"></i> {{ 
getIssuer(claim) }}</i></span>
             </div>
             <div class="col-sm">
@@ -48,19 +41,23 @@
               <button class="ml-1 btn btn-primary" 
(click)="editAttribute(claim)" *ngIf="!isClaimCred(claim) && (claim != 
claimInEdit)">
                 <span class="fa fa-edit"></span>
               </button>
+              <button *ngIf="validImportEmail" class="ml-1 btn btn-primary" 
(click)="import()">
+                <span class="fa fa-download"></span> 
{{getMessage("edit_identity_html@importFrom", {ISSUERNAME: 
getImportIssuerName()})}}
+              </button>
+
             </div>
           </div>
-          <!-- Standard "profile" claims missing on the identity -->
+          <!-- Standard "email" claims missing on the identity -->
           <div class="row mb-3" [class.openid]="inOpenIdFlow()"
               [class.text-primary]="isClaimRequested(claim) || claim == 
claimInEdit"
               [class.alert-danger]="newAttribute.name === claim.name"
-              *ngFor="let claim of missingProfileClaims">
+              *ngFor="let claim of missingEmailClaims">
             <div class="col-sm"><div style="min-width: 15em">
                 <i *ngIf="isClaimRequested(claim)" class="fa 
fa-openid"></i><b> {{ getDescription(claim) }}</b></div></div>
             <div class="col-sm">
               <!-- FIXME Allow adding of credential OR plain value -->
               <input *ngIf="claim == claimInEdit" placeholder="{{ 
getMessage('Value') }}" [(ngModel)]="claim.value">
-              <span *ngIf="claim != claimInEdit"><i 
class="text-secondary">Unset</i></span>
+              <span *ngIf="claim != claimInEdit"><i class="text-secondary">{{ 
getMessage("edit_identity_html@unset") }}</i></span>
               <!--<input *ngIf="!isClaimCred(claim)" placeholder="{{ 
getMessage('Value') }}" [(ngModel)]="claim.value">
               <span *ngIf="isClaimCred(claim)" >{{ getCredValue(claim) }} 
issued by <i>{{ getIssuer(claim) }}</i> as attribute for ``{{ claim.value 
}}''</span>-->
             </div>
@@ -73,18 +70,28 @@
               </button>
             </div>
           </div>
+          <div class="row mb-3" *ngIf="validImportEmail">
+            <!-- Instructions -->
+            <div
+              class="col-sm alert alert-primary alert-dismissible fade show 
my-2" role="alert" >
+              {{getMessage("edit_identity_html@importInfo")}}<br/>
+              
<i>{{getMessage("Note")}}</i>{{getMessage("edit_credentials_html@linkAccountInfo2")}}
+            </div>
+          </div>
       </div>
       <div class="table pb-1">
-          <!-- Standard "email" claims first -->
+          <!-- Standard "profile" claims first -->
           <div class="row mb-3" [class.openid]="inOpenIdFlow()"
               [class.text-primary]="isClaimRequested(claim) || claim == 
claimInEdit"
               [class.alert-danger]="newAttribute.name === claim.name"
-              *ngFor="let claim of existingEmailClaims">
+              *ngFor="let claim of existingProfileClaims">
             <div class="col-sm"><div style="min-width: 15em">
-                <i *ngIf="isClaimRequested(claim)" class="fa 
fa-openid"></i><b> {{ getDescription(claim) }}</b></div></div>
+                <i *ngIf="isClaimRequested(claim)" class="fa 
fa-openid"></i><b> {{ getDescription(claim) }}</b>
+              </div>
+            </div>
             <div class="col-sm">
               <input *ngIf="!isClaimCred(claim) && (claim == claimInEdit)" 
placeholder="{{ getMessage('Value') }}" [(ngModel)]="claim.value">
-              <span *ngIf="!isClaimCred(claim) && (claim != claimInEdit)">{{ 
claim.value }} <i class="text-secondary" style="float:right;"><i class="fa 
fa-certificate"></i> Self-issued</i></span>
+              <span *ngIf="!isClaimCred(claim) && (claim != claimInEdit)">{{ 
claim.value }} <i class="text-secondary" style="float:right;"><i class="fa 
fa-certificate"></i> {{ getMessage("edit_identity_html@selfissued") 
}}</i></span>
               <span *ngIf="isClaimCred(claim)"  >{{ getCredValue(claim) }} <i 
class="text-primary" style="float:right;"><i class="fa fa-certificate"></i> {{ 
getIssuer(claim) }}</i></span>
             </div>
             <div class="col-sm">
@@ -96,17 +103,17 @@
               </button>
             </div>
           </div>
-          <!-- Standard "email" claims missing on the identity -->
+          <!-- Standard "profile" claims missing on the identity -->
           <div class="row mb-3" [class.openid]="inOpenIdFlow()"
               [class.text-primary]="isClaimRequested(claim) || claim == 
claimInEdit"
               [class.alert-danger]="newAttribute.name === claim.name"
-              *ngFor="let claim of missingEmailClaims">
+              *ngFor="let claim of missingProfileClaims">
             <div class="col-sm"><div style="min-width: 15em">
                 <i *ngIf="isClaimRequested(claim)" class="fa 
fa-openid"></i><b> {{ getDescription(claim) }}</b></div></div>
             <div class="col-sm">
               <!-- FIXME Allow adding of credential OR plain value -->
               <input *ngIf="claim == claimInEdit" placeholder="{{ 
getMessage('Value') }}" [(ngModel)]="claim.value">
-              <span *ngIf="claim != claimInEdit"><i 
class="text-secondary">Unset</i></span>
+              <span *ngIf="claim != claimInEdit"><i class="text-secondary">{{ 
getMessage("edit_identity_html@unset") }}</i></span>
               <!--<input *ngIf="!isClaimCred(claim)" placeholder="{{ 
getMessage('Value') }}" [(ngModel)]="claim.value">
               <span *ngIf="isClaimCred(claim)" >{{ getCredValue(claim) }} 
issued by <i>{{ getIssuer(claim) }}</i> as attribute for ``{{ claim.value 
}}''</span>-->
             </div>
@@ -121,7 +128,6 @@
           </div>
       </div>
 
-
       <div class="table pb-1">
           <!-- Standard "address" claims first -->
           <div class="row mb-3" [class.openid]="inOpenIdFlow()"
@@ -132,7 +138,7 @@
                 <i *ngIf="isClaimRequested(claim)" class="fa 
fa-openid"></i><b> {{ getDescription(claim) }}</b></div></div>
             <div class="col-sm">
               <input *ngIf="!isClaimCred(claim) && (claim == claimInEdit)" 
placeholder="{{ getMessage('Value') }}" [(ngModel)]="claim.value">
-              <span *ngIf="!isClaimCred(claim) && (claim != claimInEdit)">{{ 
claim.value }} <i class="text-secondary" style="float:right;"><i class="fa 
fa-certificate"></i> Self-issued</i></span>
+              <span *ngIf="!isClaimCred(claim) && (claim != claimInEdit)">{{ 
claim.value }} <i class="text-secondary" style="float:right;"><i class="fa 
fa-certificate"></i> {{ getMessage("edit_identity_html@selfissued") 
}}</i></span>
               <span *ngIf="isClaimCred(claim)"  >{{ getCredValue(claim) }} <i 
class="text-primary" style="float:right;"><i class="fa fa-certificate"></i> {{ 
getIssuer(claim) }}</i></span>
             </div>
             <div class="col-sm">
@@ -155,7 +161,7 @@
             <div class="col-sm">
               <!-- FIXME Allow adding of credential OR plain value -->
               <input *ngIf="claim == claimInEdit" placeholder="{{ 
getMessage('Value') }}" [(ngModel)]="claim.value">
-              <span *ngIf="claim != claimInEdit"><i 
class="text-secondary">Unset</i></span>
+              <span *ngIf="claim != claimInEdit"><i class="text-secondary">{{ 
getMessage("edit_identity_html@unset") }}</i></span>
               <!--<input *ngIf="!isClaimCred(claim)" placeholder="{{ 
getMessage('Value') }}" [(ngModel)]="claim.value">
               <span *ngIf="isClaimCred(claim)" >{{ getCredValue(claim) }} 
issued by <i>{{ getIssuer(claim) }}</i> as attribute for ``{{ claim.value 
}}''</span>-->
             </div>
@@ -180,7 +186,7 @@
                 <i *ngIf="isClaimRequested(claim)" class="fa 
fa-openid"></i><b> {{ getDescription(claim) }}</b></div></div>
             <div class="col-sm">
               <input *ngIf="!isClaimCred(claim) && (claim == claimInEdit)" 
placeholder="{{ getMessage('Value') }}" [(ngModel)]="claim.value">
-              <span *ngIf="!isClaimCred(claim) && (claim != claimInEdit)">{{ 
claim.value }} <i class="text-secondary" style="float:right;"><i class="fa 
fa-certificate"></i> Self-issued</i></span>
+              <span *ngIf="!isClaimCred(claim) && (claim != claimInEdit)">{{ 
claim.value }} <i class="text-secondary" style="float:right;"><i class="fa 
fa-certificate"></i> {{ getMessage("edit_identity_html@selfissued") 
}}</i></span>
               <span *ngIf="isClaimCred(claim)"  >{{ getCredValue(claim) }} <i 
class="text-primary" style="float:right;"><i class="fa fa-certificate"></i> {{ 
getIssuer(claim) }}</i></span>
             </div>
             <div class="col-sm">
@@ -216,12 +222,12 @@
                 </div>
               </div>
               <input *ngIf="claim == claimInEdit && claim.flag == '0'" 
placeholder="{{ getMessage('Value') }}" [(ngModel)]="claim.value">
-              <span *ngIf="claim != claimInEdit"><i 
class="text-secondary">Unset</i></span>
+              <span *ngIf="claim != claimInEdit"><i class="text-secondary">{{ 
getMessage("edit_identity_html@unset") }}</i></span>
               <select *ngIf="claim == claimInEdit && claim.flag == '1' && 
hasCredentialSources()" class="custom-select"
                 (change)="claim.credential=$event.target.value; " >
                 <option value="">{{ 
getMessage("edit_identity_html@selectSource") }}</option>
                 <option *ngFor="let cred of credentials" value={{cred.id}}>
-                {{cred.name}}
+                {{getIssuerName(cred)}}
                 </option>
               </select>
               <div *ngIf="claim.flag == '1' && !hasCredentialSources()" 
class="alert alert-primary" role="alert">
@@ -249,7 +255,7 @@
       </div>
 
 
-      <h3 class="card-subtitle mb-2" >{{ 
getMessage("edit_identity_html@additionalInfo") }} <span (click)="showExtraInfo 
= !showExtraInfo" class="fa fa-question-circle"></span></h3>
+      <h3 class="card-subtitle mb-4" >{{ 
getMessage("edit_identity_html@additionalInfo") }} <span (click)="showExtraInfo 
= !showExtraInfo" class="fa fa-question-circle"></span></h3>
       <div class="alert alert-secondary fade show" *ngIf="showExtraInfo" >
         {{ getMessage("edit_identity_html@non_standardClaims") }}
       </div>
@@ -268,7 +274,7 @@
               <select *ngIf="isClaimCredentialRequested(missing) && 
hasCredentialSources()" class="custom-select" 
(change)="missing.credential=$event.target.value; ">
                 <option value="">{{ 
getMessage("edit_identity_html@selectSource") }}</option>
                 <option *ngFor="let cred of credentials" value={{cred.id}}>
-                  {{cred.name}}
+                {{getIssuerName(cred)}}
                 </option>
               </select>
               <div *ngIf="isClaimCredentialRequested(missing) && 
!hasCredentialSources()" class="alert alert-primary" role="alert">
@@ -299,7 +305,7 @@
             </div>
             <div class="col-sm">
               <input *ngIf="!isClaimCred(attribute) && (attribute == 
claimInEdit)" placeholder="{{ getMessage('Value') }}" 
[(ngModel)]="attribute.value">
-              <span *ngIf="!isClaimCred(attribute) && (attribute != 
claimInEdit)">{{ attribute.value }} <i class="text-secondary" 
style="float:right;"><i class="fa fa-certificate"></i> Self-issued</i></span>
+              <span *ngIf="!isClaimCred(attribute) && (attribute != 
claimInEdit)">{{ attribute.value }} <i class="text-secondary" 
style="float:right;"><i class="fa fa-certificate"></i> {{ 
getMessage("edit_identity_html@selfissued") }}</i></span>
               <span *ngIf="isClaimCred(attribute)"  >{{ 
getCredValue(attribute) }} <i class="text-primary" style="float:right;"><i 
class="fa fa-certificate"></i> {{ getIssuer(attribute) }}</i></span>
             </div>
             <div class="col-sm">
@@ -339,7 +345,7 @@
                 (change)="newAttribute.credential=$event.target.value; " >
                 <option value="">{{ 
getMessage("edit_identity_html@selectSource") }}</option>
                 <option *ngFor="let cred of credentials" value={{cred.id}}>
-                {{cred.name}}
+                {{getIssuerName(cred)}}
                 </option>
               </select>
               <div *ngIf="newAttribute.flag == '1' && !hasCredentialSources()" 
class="alert alert-primary" role="alert">
diff --git a/src/app/edit-identity/edit-identity.component.ts 
b/src/app/edit-identity/edit-identity.component.ts
index 57cbaf0..8c6a060 100644
--- a/src/app/edit-identity/edit-identity.component.ts
+++ b/src/app/edit-identity/edit-identity.component.ts
@@ -4,6 +4,7 @@ import { ReclaimService } from '../reclaim.service';
 import { Identity } from '../identity';
 import { GnsService } from '../gns.service';
 import { NamestoreService } from '../namestore.service';
+import { CredentialService } from '../credential.service';
 import { OpenIdService } from '../open-id.service';
 import { Attribute } from '../attribute';
 import { Credential } from '../credential';
@@ -11,9 +12,11 @@ import { IdentityService } from '../identity.service';
 import { finalize } from 'rxjs/operators';
 import { from, forkJoin, EMPTY } from 'rxjs';
 import { Authorization } from '../authorization';
-import { IdProvider } from '../idProvider';
 import { ConfigService } from '../config.service';
 import { LanguageService } from '../language.service';
+import { IdProvider } from '../idProvider';
+import { Scope } from '../scope';
+import { OAuthService, LoginOptions } from 'angular-oauth2-oidc';
 
 @Component({
   selector: 'app-edit-identity',
@@ -33,7 +36,6 @@ export class EditIdentityComponent implements OnInit {
   optionalClaims: Attribute[]  = [];
   webfingerEmail: string;
   authorizations: Authorization[] = [];
-  newIdProvider: IdProvider;
   emailNotFoundAlertClosed: boolean = true;
   existingProfileClaims: Attribute[] = [];
   missingProfileClaims: Attribute[] = [];
@@ -50,6 +52,13 @@ export class EditIdentityComponent implements OnInit {
   actions: string = '';
   claimInEdit: Attribute = null;
 
+  //Attribute import
+  importIdProvider: IdProvider;
+  validImportEmail: boolean = false;
+  importInProgress: boolean = false;
+  scopes: Scope[];
+  newCredential: Credential;
+
   constructor(private reclaimService: ReclaimService,
               private identityService: IdentityService,
               private gnsService: GnsService,
@@ -58,16 +67,21 @@ export class EditIdentityComponent implements OnInit {
               private activatedRoute: ActivatedRoute,
               private configService: ConfigService,
               private languageService: LanguageService,
+              private credentialService: CredentialService,
+              private oauthService: OAuthService,
               private router: Router,) {}
 
   ngOnInit() {
     this.credentialValues = {};
     this.webfingerEmail = '';
-    this.newIdProvider = new IdProvider ('', '');
+    this.importIdProvider = new IdProvider ('', '');
     this.loadAuthorizationsFromLocalStorage();
     this.identity = new Identity('','');
     this.newAttribute = new Attribute('', '', '', '', 'STRING', '0');
     this.newCredClaim = new Attribute('', '', '', '', 'STRING', '1');
+    this.newCredential = new Credential('', '', '', 'JWT', '', 0, []);
+    this.loadImportScopesFromLocalStorage()
+    this.loadImportIdProviderFromLocalStorage();
     this.activatedRoute.params.subscribe(p => {
       if (p['id'] === undefined) {
         return;
@@ -79,6 +93,9 @@ export class EditIdentityComponent implements OnInit {
               this.identity = ids[i];
               this.updateAttributes();
               this.updateCredentials();
+              /*if (this.importIdProvider.url !== '') {
+                this.tryImportCredential();
+              }*/
             }
           }
         });
@@ -146,6 +163,7 @@ export class EditIdentityComponent implements OnInit {
       this.existingPhoneClaims = 
this.cleanupClaimArray(this.existingPhoneClaims);
       this.existingAddressClaims = 
this.cleanupClaimArray(this.existingAddressClaims);
       this.updateMissingAttributes();
+      this.validateEmailForImport();
     },
     err => {
       //this.errorInfos.push("Error retrieving attributes for ``" + 
identity.name + "''");
@@ -153,6 +171,7 @@ export class EditIdentityComponent implements OnInit {
     });
   }
 
+
   inOpenIdFlow() {
     return this.oidcService.inOpenIdFlow();
   }
@@ -488,13 +507,6 @@ export class EditIdentityComponent implements OnInit {
     return this.credentials.length > 0
   }
 
-  mapIssuer(iss: string): string {
-    if (iss == "https://omejdn.nslab.ch";) {
-      return "Berner Fachhochschule";
-    }
-    return iss;
-  }
-
   //FIXME credentials need an issuer field
   getIssuer(attribute: Attribute) {
     for (let i = 0; i < this.credentials.length; i++) {
@@ -560,4 +572,216 @@ export class EditIdentityComponent implements OnInit {
   editAttribute(claim: Attribute) {
     this.claimInEdit = claim;
   }
+
+  loadImportScopesFromLocalStorage(){
+    this.scopes = [];
+    var loadedScopes = localStorage.getItem("scopes");
+    if (loadedScopes==null){
+      return
+    }
+    loadedScopes.split(',{').forEach(scopeObject => {
+      var scopeName = scopeObject.split(',')[0];
+      var scopeChosen = scopeObject.split(',')[1].slice(0, -1);
+      const scopeInterface: Scope = {
+        scope: scopeName.split(':')[1].slice(1,-1),
+        chosen: (/true/i).test(scopeChosen.split(':')[1]),
+      }
+      this.scopes.push(scopeInterface)
+    }
+      );
+  }
+
+  loadImportIdProviderFromLocalStorage(){
+    this.importIdProvider.url = localStorage.getItem("importIdProviderURL") || 
'';
+    this.importIdProvider.name = this.importIdProvider.url.split('//')[1];
+  }
+
+  tryImportCredential() {
+    if (this.importIdProvider.url === '') {
+        return;
+    }
+    const loginOptions: LoginOptions = {
+      customHashFragment: "?code="+localStorage.getItem("credentialCode") + 
"&state=" + localStorage.getItem("credentialState") + "&session_state="+ 
localStorage.getItem("credentialSession_State"),
+    }
+    this.configureOauthService();
+    if (!localStorage.getItem("credentialCode")){
+      this.oauthService.loadDiscoveryDocumentAndTryLogin().then(success => {
+        if (!success || (null == this.oauthService.getIdToken())) {
+          this.importInProgress = false;
+          return;
+        }
+        console.log("Login successful: "+this.oauthService.getIdToken());
+        this.newCredential.name = this.importIdProvider.name + "oidcjwt";
+        this.newCredential.value = this.oauthService.getIdToken();
+        this.importAttributesFromCredential();
+      });
+    } else {
+      
this.oauthService.loadDiscoveryDocumentAndTryLogin(loginOptions).then(success 
=> {
+        if (!success || (null == this.oauthService.getIdToken())) {
+          this.importInProgress = false;
+          return;
+        }
+        console.log("Login successful: "+this.oauthService.getIdToken());
+        this.newCredential.name = this.importIdProvider.name + "oidcjwt";
+        this.newCredential.value = this.oauthService.getIdToken();
+        this.importAttributesFromCredential();
+      });
+    }
+  }
+
+  importAttributesFromCredential() {
+    this.importInProgress = true;
+    this.reclaimService.addCredential(this.identity, 
this.newCredential).subscribe(res => {
+      console.log("Stored credential");
+      this.reclaimService.getCredentials(this.identity).subscribe(creds => {
+        this.reclaimService.getAttributes(this.identity).subscribe(attrs => {
+          var promises = [];
+          var cred = null;
+          for (var c of creds) {
+            if (c.name == this.newCredential.name) {
+              cred = c;
+            }
+          }
+          if (null == cred) {
+            console.log("ERROR: credential was not added!");
+            this.importInProgress = false;
+            return;
+          }
+          console.log("Trying to import " + cred.attributes.length + " 
attributes");
+
+          for (let attr of cred.attributes) {
+            if ((attr.name == "sub") ||
+                (attr.name == "nonce") ||
+                (attr.name == "email_verified") ||
+                (attr.name == "phone_number_verified")) {
+              continue;
+            }
+            //New attribute with name == claim name
+            var attestation = new Attribute(attr.name, '', cred.id, attr.name, 
'STRING', '1');
+            for (let existAttr of attrs) {
+              /* Overwrite existing */
+              if (existAttr.name !== attr.name) {
+                continue;
+              }
+              attestation.id = existAttr.id;
+              break;
+            }
+            promises.push(
+              from(this.reclaimService.addAttribute(this.identity, 
attestation)));
+          //promises = promises.concat (this.storeAttribute(attestation));
+          }
+          forkJoin(promises)
+          .pipe(
+            finalize(() => {
+              this.importIdProvider.url = '';
+              this.importIdProvider.name = '';
+              localStorage.removeItem('importIdProviderURL');
+              localStorage.removeItem("credentialCode");
+              this.importInProgress = false;
+              this.oauthService.logOut();
+              this.updateAttributes();
+              this.updateCredentials();
+            })
+          ).subscribe(res => {
+            console.log("Finished attribute import.");
+          },
+          err => {
+            console.log(err);
+          });
+        });
+      });
+    });
+  }
+
+  validateEmailForImport() {
+    var emailAddr = null;
+    for (let attr of this.attributes) {
+      if (attr.name !== 'email') {
+        continue;
+      }
+      console.log("Found email attribute " + attr.value);
+      emailAddr = attr.value;
+      break;
+    }
+    if ((null == emailAddr) ||
+        !emailAddr.includes('@')) {
+      this.validImportEmail = false;
+      return;
+    }
+    if (emailAddr.length - emailAddr.indexOf('@') < 4) {
+      this.validImportEmail = false;
+      return;
+    }
+    this.discoverIdProvider(emailAddr);
+  }
+
+  discoverIdProvider(emailAddr: string) {
+    localStorage.setItem('userForCredential', this.identity.name);
+    let account = emailAddr;
+    if (this.configService.get().experiments) {
+      if (emailAddr.substr(emailAddr.indexOf('@')+1) === 
'aisec.fraunhofer.de') {
+        account = emailAddr.substr(0, emailAddr.indexOf('@')+1) + 
'as.aisec.fraunhofer.de';
+      } else if (emailAddr.substr(emailAddr.indexOf('@')+1) === 'bfh.ch') {
+        account = emailAddr.substr(0, emailAddr.indexOf('@')+1) + 
'omejdn.nslab.ch';
+      }
+    }
+    this.credentialService.getLink(account).subscribe (idProvider => {
+      this.importIdProvider = new IdProvider((idProvider.links[0]).href,
+                                             
(idProvider.links[0]).href.split('//')[1]);
+      localStorage.setItem('importIdProviderURL', this.importIdProvider.url);
+      this.getImportScopes();
+      console.log(this.importIdProvider.url);
+      this.validImportEmail = true;
+      this.tryImportCredential();
+    },
+    error => {
+      this.validImportEmail = false;
+      console.log (error);
+    });
+  }
+
+  mapIssuer(iss: string): string {
+    if (iss.includes("omejdn.nslab.ch")) {
+      return "Berner Fachhochschule";
+    }
+    return iss;
+  }
+
+
+  getImportIssuerName() {
+    return this.mapIssuer(this.importIdProvider.name);
+  }
+
+  getIssuerName(cred: Credential) {
+    return this.mapIssuer(cred.name);
+  }
+
+  import(){
+    this.configureOauthService();
+    this.oauthService.logOut(); //Make sure we logout before login
+    this.oauthService.loadDiscoveryDocumentAndLogin();
+  }
+
+  configureOauthService(){
+    var authCodeFlowConfig = 
this.credentialService.getOauthConfig(this.importIdProvider, this.scopes);
+    this.oauthService.configure(authCodeFlowConfig);
+  }
+
+  getImportScopes(){
+    this.configureOauthService();
+    
this.credentialService.getDiscoveryDocument(this.oauthService.issuer).subscribe(openidConfig
 => {
+      this.scopes = [];
+      openidConfig["scopes_supported"].forEach(scope => {
+        const scopeInterface: Scope = {
+          scope: scope,
+          chosen: true,
+        }
+        this.scopes.push(scopeInterface)
+      });
+      localStorage.setItem("scopes", JSON.stringify(this.scopes));
+      });
+  }
+
+
+
 }
diff --git a/src/locales/de/messages.json b/src/locales/de/messages.json
index ec2500f..67207c3 100644
--- a/src/locales/de/messages.json
+++ b/src/locales/de/messages.json
@@ -50,8 +50,13 @@
     "edit_credentials_ts@noAccount": "Kein Konto mit diese E-Email Addresse 
gefunden",
     "edit_credentials_ts@errorWrongAddress": "Ein Fehler ist aufgetreten - Der 
Grund könnte eine falsche E-Email Adresse sein.",
     "edit_identity_html@basicInfo": "Gebräuchliche Informationen",
+    "edit_identity_html@importInfo": "Über den 'Importieren'-Knopf kannst du 
gegebenenfalls Attribute aus einem existierenden Konto importieren.",
+    "edit_identity_html@linkAccount": "Attribute importieren",
+
     "edit_identity_html@standardScopes": "Die unten stehenden Attribute 
entsprechen den standard \"scopes\" von OpenID Connect:\n``profile'', 
``email'', ``phone'' and ``address''.",
-    "edit_identity_html@claimAsAttribute": "{{CREDVALUE}} ausgestellt von 
{{ISSUER}} als Attribut für ``{{CLAIMVALUE}}''",
+    "edit_identity_html@selfissued": "Selbst ausgestellt",
+    "edit_identity_html@importFrom": "Von ``{{ISSUERNAME}}´´ importieren",
+    "edit_identity_html@unset": "Nicht gesetzt",
     "edit_identity_html@attribute": "Attribut",
     "edit_identity_html@plain": "Text",
     "edit_identity_html@credential": "Attestierung",
diff --git a/src/locales/en/messages.json b/src/locales/en/messages.json
index a965f3f..4679ec0 100644
--- a/src/locales/en/messages.json
+++ b/src/locales/en/messages.json
@@ -53,11 +53,12 @@
     "edit_credentials_ts@noAccount": "No account found with this email",
     "edit_credentials_ts@errorWrongAddress": "An Error has occured - This may 
have been caused by a wrong e-mail address.",
     "edit_identity_html@basicInfo": "Basic user information",
-    "edit_identity_html@noAttributes": "This identity seems to not yet have 
any attributes!",
-    "edit_identity_html@importInfo": "You can import attributes from an 
existing online account or manually add your own below.",
+    "edit_identity_html@importInfo": "You may be able to import attributes 
from an existing online account by clicking the 'Import' button.",
     "edit_identity_html@linkAccount": "Import attributes",
     "edit_identity_html@standardScopes": "The attributes below correspond to 
the standard scopes of the\nOpenID Connect specification: ``profile'', 
``email'', ``phone'' and ``address''.",
-    "edit_identity_html@claimAsAttribute": "{{CREDVALUE}} issued by {{ISSUER}} 
as attribute for ``{{CLAIMVALUE}}''",
+    "edit_identity_html@selfissued": "Self-issued",
+    "edit_identity_html@importFrom": "Import from ``{{ISSUERNAME}}´´",
+    "edit_identity_html@unset": "Unset",
     "edit_identity_html@attribute": "Attribute",
     "edit_identity_html@plain": "Plain",
     "edit_identity_html@credential": "Credential",

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]