gnunet-svn
[Top][All Lists]
Advanced

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

[reclaim-ui] 154/459: start extracting components


From: gnunet
Subject: [reclaim-ui] 154/459: start extracting components
Date: Fri, 11 Jun 2021 23:24:06 +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 624cd829967891c80a8ec3ea0b963853c56cdb42
Author: Schanzenbach, Martin <mschanzenbach@posteo.de>
AuthorDate: Tue Dec 10 17:24:36 2019 +0100

    start extracting components
---
 src/app/app-routing.module.ts                      |   4 +
 src/app/app.module.ts                              |   6 +-
 src/app/edit-identity/edit-identity.component.css  |   0
 src/app/edit-identity/edit-identity.component.html | 126 ++++++++
 src/app/edit-identity/edit-identity.component.ts   | 331 +++++++++++++++++++++
 src/app/identity-list/identity-list.component.html | 169 +----------
 src/app/identity-list/identity-list.component.ts   | 287 +-----------------
 src/app/new-identity/new-identity.component.css    |   0
 src/app/new-identity/new-identity.component.html   |  31 ++
 src/app/new-identity/new-identity.component.ts     |  83 ++++++
 src/app/open-id.service.ts                         |   6 -
 11 files changed, 594 insertions(+), 449 deletions(-)

diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts
index 699b222..30f732c 100644
--- a/src/app/app-routing.module.ts
+++ b/src/app/app-routing.module.ts
@@ -1,11 +1,15 @@
 import { NgModule } from '@angular/core';
 import { RouterModule, Routes } from '@angular/router';
 import { IdentityListComponent } from 
'./identity-list/identity-list.component';
+import { NewIdentityComponent } from './new-identity/new-identity.component';
+import { EditIdentityComponent } from 
'./edit-identity/edit-identity.component';
 
 const routes: Routes = [
     { path: 'index.html', component: IdentityListComponent },
     // { path: 'identities', component: IdentityListComponent },
     { path: '', redirectTo: '/index.html', pathMatch: 'full' },
+    { path: 'new-identity', component: NewIdentityComponent },
+    { path: 'edit-identity/:id', component: EditIdentityComponent },
 ];
 
 @NgModule({
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 99ba0ae..77d4efb 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -15,13 +15,17 @@ import { ModalComponent } from './modal.component';
 import { ModalService } from './modal.service';
 import { SearchPipe } from './search.pipe';
 import { OpenIdService } from './open-id.service';
+import { NewIdentityComponent } from './new-identity/new-identity.component';
+import { EditIdentityComponent } from 
'./edit-identity/edit-identity.component';
 
 @NgModule({
   declarations: [
     AppComponent,
     IdentityListComponent,
     ModalComponent,
-    SearchPipe
+    SearchPipe,
+    NewIdentityComponent,
+    EditIdentityComponent
   ],
   imports: [
     BrowserModule,
diff --git a/src/app/edit-identity/edit-identity.component.css 
b/src/app/edit-identity/edit-identity.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/edit-identity/edit-identity.component.html 
b/src/app/edit-identity/edit-identity.component.html
new file mode 100644
index 0000000..d854707
--- /dev/null
+++ b/src/app/edit-identity/edit-identity.component.html
@@ -0,0 +1,126 @@
+<!-- Identity edit screen -->
+<div class="m-2 card">
+  <div class="card-avatar card-img-top">
+    <div class="card-avatar-character text-dark">
+      Manage identity: <i>{{ identity.name }}</i>
+    </div>
+  </div>
+  <!-- Attribute table -->
+  <div class="card-body">
+    <div>
+      <h6 class="card-subtitle mb-2">Attributes:</h6>
+      <!-- Missing attributes -->
+      <table class="table pb-1" *ngIf="isAttributeMissing()">
+        <tbody>
+          <tr [class.openid]="inOpenIdFlow()" 
[class.alert-danger]="newAttribute.name === missing.name" class="text-primary" 
*ngFor="let missing of missingAttributes">
+            <td><div style="min-width: 15em">{{missing.name}}</div></td>
+            <td>
+              <input placeholder="Value" [(ngModel)]="missing.value">
+            </td>
+            <td>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+      <!-- Requested attributes -->
+      <table class="table pb-1" style="">
+        <tbody>
+          <tr [class.openid]="inOpenIdFlow()" 
[class.text-primary]="isRequested(attribute)" 
[class.alert-danger]="newAttribute.name === attribute.name" *ngFor="let 
attribute of attributes">
+            <td><div style="min-width: 15em">{{ attribute.name }}</div></td>
+            <td>
+              <input placeholder="Value" [(ngModel)]="attribute.value">
+            </td>
+            <td>
+              <button class="btn btn-primary" 
(click)="deleteAttribute(attribute)">
+                <span class="fa fa-trash"></span>
+              </button>
+            </td>
+          </tr>
+          <tr [class.alert-danger]="isInConflict(newAttribute)">
+            <td>
+              <input [class.text-danger]="!attributeNameValid(newAttribute)" 
placeholder="Attribute" [(ngModel)]="newAttribute.name">
+            </td>
+            <td>
+              <input placeholder="Value" 
[class.text-danger]="!attributeValueValid(newAttribute)" 
[(ngModel)]="newAttribute.value">
+            </td>
+            <td>
+              <button [disabled]="!canAddAttribute(newAttribute)" class="btn 
btn-primary"  (click)="addAttribute(newAttribute)">
+                <span class="fa fa-plus"></span> 
+              </button>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+    <!-- Attribute creation warning -->
+    <div *ngIf="!attributeNameValid(newAttribute) || 
!attributeValueValid(newAttribute)" class="alert alert-primary 
alert-dismissible fade show" role="alert">
+      <span class="fa fa-warning"></span> Note:
+      <ul>
+        <li>Only use alphanumeric attribute names.</li>
+        <li>You cannot define the same name twice.</li>
+        <li>Attribute values may not be empty!</li>
+      </ul>
+    </div>
+    <!-- Authorized entities -->
+    <div style="margin-top: 1.5em;">
+      <table class="table pb-1" *ngIf="showTicketsIdentity">
+        <thead style="border-top-style: hidden">
+          <tr>
+            <th scope="col">
+              <h6 class="card-subtitle mb-2">
+                Authorized Entities:
+              </h6>
+            </th>
+            <th scope="col">
+              <h6 class="card-subtitle mb-2">
+                Shared attributes:
+              </h6>
+            </th>
+            <th scope="col"></th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr *ngFor="let ticket of tickets">
+            <td>
+              <div style="min-width: 15em">
+                {{getAudienceName(ticket)}}
+              </div>
+            </td>
+            <td>
+              <div style="min-width: 15em">
+                {{ticketAttributeMapper[ticket.audience]}}
+              </div>
+            </td>
+            <td>
+              <button class="btn btn-primary" *ngIf="showConfirmRevoke != 
ticket" (click)="confirmRevoke(ticket)">
+                <span class="fa fa-unlink"></span> Revoke
+              </button>
+              <div class="alert alert-danger fade show" 
*ngIf="showConfirmRevoke == ticket">
+                Do you really want to revoke this authorization?<br/><br/>
+                <button class="btn btn-primary m-2" 
(click)="revokeTicket(ticket)">
+                  <span class="fa fa-check"></span> Yes
+                </button>
+                <button class="btn btn-primary m-2" 
(click)="hideConfirmRevoke()">
+                  <span class="fa fa-close"></span> No
+                </button>
+              </div>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+    <!-- Edit card buttons -->
+    <div>
+      <button class="btn btn-primary" (click)="saveIdentityAttributes()" 
[disabled]="!canSaveIdentity()">
+        <span class="fa fa-save"></span> Save and Back
+      </button>
+        <button *ngIf="(0 < tickets?.length) && !inOpenIdFlow()" class="btn 
btn-primary" (click)="toggleShowTickets()" [style.float]="'right'">
+        <span class="fa fa-openid"></span>
+        <span *ngIf="showTicketsIdentity"> Hide</span>
+        <span *ngIf="!showTicketsIdentity"> Show</span> 
+        authorizations
+      </button>
+    </div>
+  </div>
+</div>
+
diff --git a/src/app/edit-identity/edit-identity.component.ts 
b/src/app/edit-identity/edit-identity.component.ts
new file mode 100644
index 0000000..8acae63
--- /dev/null
+++ b/src/app/edit-identity/edit-identity.component.ts
@@ -0,0 +1,331 @@
+import { Component, OnInit } from '@angular/core';
+import { ActivatedRoute, Router } from '@angular/router';
+import { ReclaimService } from '../reclaim.service';
+import { Ticket } from '../ticket';
+import { Identity } from '../identity';
+import { GnsService } from '../gns.service';
+import { NamestoreService } from '../namestore.service';
+import { OpenIdService } from '../open-id.service';
+import { Attribute } from '../attribute';
+import { IdentityService } from '../identity.service';
+import { finalize } from 'rxjs/operators';
+import { from, forkJoin, EMPTY } from 'rxjs';
+
+@Component({
+  selector: 'app-edit-identity',
+  templateUrl: './edit-identity.component.html',
+  styleUrls: ['./edit-identity.component.css']
+})
+export class EditIdentityComponent implements OnInit {
+
+  tickets: {};
+  identity: Identity;
+  audienceNames: {};
+  showTickets: Boolean;
+  ticketAttributeMapper: {};
+  attributes: Attribute[];
+  requestedAttributes: Attribute[];
+  missingAttributes: Attribute[];
+  newAttribute: Attribute;
+  showConfirmRevoke: any;
+
+  constructor(private reclaimService: ReclaimService,
+              private identityService: IdentityService,
+              private gnsService: GnsService,
+              private oidcService: OpenIdService,
+              private namestoreService: NamestoreService,
+              private activatedRoute: ActivatedRoute,
+              private router: Router) { }
+
+  ngOnInit() {
+    this.tickets = {};
+    this.attributes = [];
+    this.showConfirmRevoke = null;
+    this.identity = new Identity('','');
+    this.newAttribute = new Attribute('', '', '', 'STRING');
+    this.ticketAttributeMapper = {};
+    this.activatedRoute.params.subscribe(p => {
+      if (p['id'] === undefined) {
+        return;
+      }
+      this.identityService.getIdentities().subscribe(
+        ids => {
+          for (let i = 0; i < ids.length; i++) {
+            if (ids[i].name == p['id']) {
+              this.identity = ids[i];
+              this.updateAttributes();
+            }
+          }
+        });
+    });
+  }
+
+  confirmRevoke(ticket) { this.showConfirmRevoke = ticket;}
+
+  hideConfirmRevoke() { this.showConfirmRevoke = null; }
+
+  private mapAudience(ticket) {
+    this.gnsService.getClientName(ticket.audience).subscribe(records => {
+      for (let i = 0; i < records.data.length; i++) {
+        if (records.data[i].record_type !== 'RECLAIM_OIDC_CLIENT') {
+          continue;
+        }
+        this.audienceNames[ticket.audience] = records.data[i].value;
+        break;
+      }
+    });
+  }
+
+  private updateTickets() {
+    this.reclaimService.getTickets(this.identity).subscribe(tickets => {
+      this.tickets = [];
+      if (tickets === null) {
+        return;
+      }
+      this.tickets = tickets;
+      tickets.forEach(ticket => {
+        this.mapAudience(ticket);
+        this.mapAttributes(ticket);
+      });
+    },
+    err => {
+      //this.errorInfos.push("Unable to retrieve tickets for identity ``" + 
identity.name + "''");
+      console.log(err);
+    });
+  }
+  
+  private mapAttributes(ticket) {
+    this.namestoreService.getNames(this.identity).subscribe(names => {
+      this.ticketAttributeMapper[ticket.audience] = [];
+      names = names.filter(name => name.record_name === 
ticket.rnd.toLowerCase());
+      for (let i = 0; i < names.length; i++) {
+        names[i].data.forEach(record => {
+          if (record.record_type === 'RECLAIM_ATTR_REF') {
+            this.attributes
+              .filter(attr => attr.id === record.value)
+              .map(attr => {
+                this.ticketAttributeMapper[ticket.audience].push(attr.name);
+              });
+          }
+        });
+      }
+    });
+  }
+
+  toggleShowTickets(identity) {
+    this.showTickets = !this.showTickets;
+  }
+
+  revokeTicket(ticket) {
+    this.reclaimService.revokeTicket(ticket).subscribe(
+      result => {
+        this.updateAttributes();
+      },
+      err => {
+        //this.errorInfos.push("Unable to revoke ticket.");
+        console.log(err);
+      });
+  }
+  
+  private updateAttributes() {
+    this.reclaimService.getAttributes(this.identity).subscribe(attributes => {
+      this.attributes = [];
+      this.requestedAttributes = [];
+      if (attributes === null) {
+        this.getMissingAttributes();
+        return;
+      }
+      let i;
+      for (i = 0; i < attributes.length; i++) {
+        this.attributes.push(attributes[i]);
+        if (this.oidcService.getScope().includes(attributes[i].name)) {
+          this.requestedAttributes.push(attributes[i]);
+        }
+      }
+      this.getMissingAttributes();
+      this.updateTickets();
+    },
+    err => {
+      //this.errorInfos.push("Error retrieving attributes for ``" + 
identity.name + "''");
+      console.log(err);
+    });
+  }
+
+  inOpenIdFlow() {
+    return this.oidcService.inOpenIdFlow();
+  }
+
+  isRequested(attribute) {
+    if (undefined === this.requestedAttributes) {
+      return false;
+    } else {
+      return -1 !==
+        this.requestedAttributes.indexOf(attribute);
+    }
+  }
+
+  getMissingAttributes() {
+    const scopes = this.oidcService.getScope();
+    let i;
+    for (i = 0; i < this.requestedAttributes.length; i++) {
+      const j =
+        scopes.indexOf(this.requestedAttributes[i].name);
+      if (j >= 0) {
+        scopes.splice(j, 1);
+      }
+    }
+    this.missingAttributes = [];
+    for (i = 0; i < scopes.length; i++) {
+      const attribute = new Attribute('', '', '', 'STRING');
+      attribute.name = scopes[i];
+      this.missingAttributes.push(attribute);
+    }
+  }
+
+  isInConflict(attribute) {
+    let i;
+    if (undefined !== this.missingAttributes) {
+      for (i = 0; i < this.missingAttributes.length; i++) {
+        if (attribute.name ===
+          this.missingAttributes[i].name) {
+          return true;
+        }
+      }
+    }
+    if (undefined !== this.attributes) {
+      for (i = 0; i < this.attributes.length; i++) {
+        if (attribute.name === this.attributes[i].name) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  canAddAttribute(attribute) {
+    if ((attribute.name === '') || (attribute.value === '')) {
+      return false;
+    }
+    if (attribute.name.indexOf(' ') >= 0) {
+      return false;
+    }
+    return !this.isInConflict(attribute);
+  }
+
+  canSaveIdentity(identity) {
+    if (this.canAddAttribute(this.newAttribute)) {
+      return true;
+    }
+    return ((this.newAttribute.name === '') &&
+      (this.newAttribute.value === '')) &&
+      !this.isInConflict(this.newAttribute);
+  }
+
+  saveIdentityAttributes() {
+    this.storeAttributes()
+      .pipe(
+        finalize(() => {
+          this.newAttribute.name = '';
+          this.newAttribute.value = '';
+          this.newAttribute.type = 'STRING';
+        }))
+      .subscribe(res => {
+        //FIXME success dialog/banner
+        this.updateAttributes();
+        this.router.navigate(['/']);
+      },
+      err => {
+        console.log(err);
+        //this.errorInfos.push("Failed to update identity ``" +  
this.identityInEdit.name + "''");
+      });
+  }
+
+
+  deleteAttribute(attribute) {
+    this.reclaimService.deleteAttribute(this.identity, attribute)
+      .subscribe(res => {
+        //FIXME info dialog
+        this.updateAttributes();
+      },
+      err => {
+        //this.errorInfos.push("Failed to delete attribute ``" + 
attribute.name + "''");
+        console.log(err);
+      });
+  }
+
+  private storeAttributes() {
+    const promises = [];
+    let i;
+    if (undefined !== this.missingAttributes) {
+      for (i = 0; i < this.missingAttributes.length; i++) {
+        if (this.missingAttributes[i].value === '') {
+          continue;
+        }
+        promises.push(from(this.reclaimService.addAttribute(
+          this.identity, this.missingAttributes[i])));
+      }
+    }
+    if (undefined !== this.attributes) {
+      for (i = 0; i < this.attributes.length; i++) {
+        promises.push(
+          from(this.reclaimService.addAttribute(this.identity, 
this.attributes[i])));
+      }
+    }
+    if (this.newAttribute.value !== '') {
+      promises.push(from(this.reclaimService.addAttribute(this.identity, 
this.newAttribute)));
+    }
+
+    return forkJoin(promises);
+  }
+
+  addAttribute() {
+    this.storeAttributes()
+      .pipe(
+        finalize(() => {
+          this.newAttribute.name = '';
+          this.newAttribute.value = '';
+          this.newAttribute.type = 'STRING';
+          this.updateAttributes;
+        }))
+      .subscribe(res => {
+        console.log(res);
+      },
+      err => {
+        console.log(err);
+        //this.errorInfos.push("Failed to update identity ``" +  
this.identityInEdit.name + "''");
+        EMPTY
+      });
+  }
+
+  attributeNameValid(attribute) {
+    if (attribute.name === '' && attribute.value === '') {
+      return true;
+    }
+    if (attribute.name.indexOf(' ') >= 0) {
+      return false;
+    }
+    if (!/^[a-zA-Z0-9-]+$/.test(attribute.name)) {
+      return false;
+    }
+    return !this.isInConflict(attribute);
+  }
+
+  attributeValueValid(attribute) {
+    if (attribute.value === '') {
+      return attribute.name === '';
+    }
+    return true;
+  }
+
+  isAttributeMissing() {
+    if (!this.oidcService.inOpenIdFlow()) {
+      return false;
+    }
+    if (undefined === this.requestedAttributes) {
+      return false;
+    }
+    return this.oidcService.getScope().length !==
+      this.requestedAttributes.length;
+  }
+
+}
diff --git a/src/app/identity-list/identity-list.component.html 
b/src/app/identity-list/identity-list.component.html
index 2e4c200..2329f24 100644
--- a/src/app/identity-list/identity-list.component.html
+++ b/src/app/identity-list/identity-list.component.html
@@ -65,7 +65,7 @@
 
 <!-- Cancel authorization -->
 <div style="margin-bottom: 1em; text-align: center;">
-  <button *ngIf="inOpenIdFlow() && !isAddIdentity() && (null == 
identityInEdit) && clientNameFound" class="btn btn-danger mt-2" 
(click)="cancelRequest()">
+  <button *ngIf="inOpenIdFlow() && clientNameFound" class="btn btn-danger 
mt-2" (click)="cancelRequest()">
     <span class="fa fa-ban"></span> Decline authorization request
   </button>
 </div>
@@ -81,146 +81,20 @@
 </div>
 
 <!-- No identities present -->
-<div *ngIf="isConnected() && 0 == identities.length && !isAddIdentity()" 
style="text-align: center;" class="alert alert-secondary alert-dismissible fade 
show" role="alert">
+<div *ngIf="isConnected() && 0 == identities.length" style="text-align: 
center;" class="alert alert-secondary alert-dismissible fade show" role="alert">
   You don't have any identities yet.<br/><br/>
   <button class="btn btn-primary" (click)="addIdentity()">
     <span class="fa fa-plus"></span> Add your first identity!
   </button>
 </div>
 
-<!-- Identity edit screen -->
-<div class="m-2 card" *ngIf="(null != identityInEdit) && !isAddIdentity()">
-  <div class="card-avatar card-img-top">
-    <div class="card-avatar-character text-dark">
-      Manage identity: <i>{{ identityInEdit.name }}</i>
-    </div>
-  </div>
-  <!-- Attribute table -->
-  <div class="card-body">
-    <div>
-      <h6 class="card-subtitle mb-2">Attributes:</h6>
-      <!-- Missing attributes -->
-      <table class="table pb-1" *ngIf="isAttributeMissing(identityInEdit)">
-        <tbody>
-          <tr [class.openid]="inOpenIdFlow()" 
[class.alert-danger]="newAttribute.name === missing.name" class="text-primary" 
*ngFor="let missing of missingAttributes[identityInEdit.pubkey]">
-            <td><div style="min-width: 15em">{{missing.name}}</div></td>
-            <td>
-              <input placeholder="Value" [(ngModel)]="missing.value">
-            </td>
-            <td>
-            </td>
-          </tr>
-        </tbody>
-      </table>
-      <!-- Requested attributes -->
-      <table class="table pb-1" style="">
-        <tbody>
-          <tr [class.openid]="inOpenIdFlow()" 
[class.text-primary]="isRequested(identityInEdit, attribute)" 
[class.alert-danger]="newAttribute.name === attribute.name" *ngFor="let 
attribute of attributes[identityInEdit.pubkey]">
-            <td><div style="min-width: 15em">{{attribute.name}}</div></td>
-            <td>
-              <input placeholder="Value" [(ngModel)]="attribute.value">
-            </td>
-            <td>
-              <button class="btn btn-primary" 
(click)="deleteAttribute(attribute)">
-                <span class="fa fa-trash"></span>
-              </button>
-            </td>
-          </tr>
-          <tr [class.alert-danger]="isInConflict(identityInEdit,newAttribute)">
-            <td>
-              <input 
[class.text-danger]="!attributeNameValid(identityInEdit,newAttribute)" 
placeholder="Attribute" [(ngModel)]="newAttribute.name">
-            </td>
-            <td>
-              <input placeholder="Value" 
[class.text-danger]="!attributeValueValid(newAttribute)" 
[(ngModel)]="newAttribute.value">
-            </td>
-            <td>
-              <button 
[disabled]="!canAddAttribute(identityInEdit,newAttribute)" class="btn 
btn-primary"  (click)="addAttribute(newAttribute)">
-                <span class="fa fa-plus"></span> 
-              </button>
-            </td>
-          </tr>
-        </tbody>
-      </table>
-    </div>
-    <!-- Attribute creation warning -->
-    <div *ngIf="!attributeNameValid(identityInEdit,newAttribute) || 
!attributeValueValid(newAttribute)" class="alert alert-primary 
alert-dismissible fade show" role="alert">
-      <span class="fa fa-warning"></span> Note:
-      <ul>
-        <li>Only use alphanumeric attribute names.</li>
-        <li>You cannot define the same name twice.</li>
-        <li>Attribute values may not be empty!</li>
-      </ul>
-    </div>
-    <!-- Authorized entities -->
-    <div style="margin-top: 1.5em;">
-      <table class="table pb-1" *ngIf="identityInEdit == showTicketsIdentity">
-        <thead style="border-top-style: hidden">
-          <tr>
-            <th scope="col">
-              <h6 class="card-subtitle mb-2" *ngIf="identityInEdit == 
showTicketsIdentity">
-                Authorized Entities:
-              </h6>
-            </th>
-            <th scope="col">
-              <h6 class="card-subtitle mb-2" *ngIf="identityInEdit == 
showTicketsIdentity">
-                Shared attributes:
-              </h6>
-            </th>
-            <th scope="col"></th>
-          </tr>
-        </thead>
-        <tbody>
-          <tr *ngFor="let ticket of tickets[identityInEdit.pubkey]">
-            <td>
-              <div style="min-width: 15em">
-                {{getAudienceName(ticket)}}
-              </div>
-            </td>
-            <td>
-              <div style="min-width: 15em">
-                {{ticketAttributeMapper[ticket.audience]}}
-              </div>
-            </td>
-            <td>
-              <button class="btn btn-primary" *ngIf="showConfirmRevoke != 
ticket" (click)="confirmRevoke(ticket)">
-                <span class="fa fa-unlink"></span> Revoke
-              </button>
-              <div class="alert alert-danger fade show" 
*ngIf="showConfirmRevoke == ticket">
-                Do you really want to revoke this authorization?<br/><br/>
-                <button class="btn btn-primary m-2" 
(click)="revokeTicket(identityInEdit, ticket)">
-                  <span class="fa fa-check"></span> Yes
-                </button>
-                <button class="btn btn-primary m-2" 
(click)="hideConfirmRevoke()">
-                  <span class="fa fa-close"></span> No
-                </button>
-              </div>
-            </td>
-          </tr>
-        </tbody>
-      </table>
-    </div>
-    <!-- Edit card buttons -->
-    <div>
-      <button class="btn btn-primary" 
(click)="saveIdentityAttributes(identityInEdit)" 
[disabled]="!canSaveIdentity(identityInEdit)">
-        <span class="fa fa-save"></span> Save and Back
-      </button>
-        <button *ngIf="(0 < tickets[identityInEdit.pubkey]?.length) && 
!inOpenIdFlow()" class="btn btn-primary" 
(click)="toggleShowTickets(identityInEdit)" [style.float]="'right'">
-        <span class="fa fa-openid"></span>
-        <span *ngIf="identityInEdit == showTicketsIdentity"> Hide</span>
-        <span *ngIf="identityInEdit != showTicketsIdentity"> Show</span> 
-        authorizations
-      </button>
-    </div>
-  </div>
-</div>
-
 <!-- Identity cards -->
 <!-- No match -->
 <div *ngIf="canSearch()">
   <div *ngIf="(identities | search: searchTerm).length == 0" 
style="text-align: center;" class="alert alert-secondary alert-dismissible fade 
show" role="alert">No matching identities.</div>
 </div>
 <!-- Cards -->
-<div class="card-columns p-2" *ngIf="(null == identityInEdit) && 
!isAddIdentity()">
+<div class="card-columns p-2">
   <div class="card" *ngFor="let identity of identities | search: searchTerm">
     <div class="card-avatar card-img-top">
       <div class="card-avatar-character text-dark">
@@ -230,7 +104,7 @@
         <button class="btn btn-primary" *ngIf="showConfirmDelete != identity" 
(click)="confirmDelete(identity)">
           <span class="fa fa-trash"></span>
         </button>
-        <button class="btn btn-primary" *ngIf="showConfirmDelete != identity" 
(click)="editIdentity(identity)">
+        <button class="btn btn-primary" *ngIf="showConfirmDelete != identity" 
[routerLink]="['/edit-identity', identity.name]">
           <span class="fa fa-edit"></span>
         </button>
       </div>
@@ -265,7 +139,7 @@
         <table class="table pb-1">
           <tbody>
             <tr [class.openid]="inOpenIdFlow()" 
[class.text-primary]="isRequested(identity, attribute)"
-               [class.alert-danger]="newAttribute.name === attribute.name" 
*ngFor="let attribute of attributes[identity.pubkey]">
+               *ngFor="let attribute of attributes[identity.pubkey]">
               <td>
                 <div style="min-width: 15em"><span 
*ngIf="isRequested(identity, attribute)" class="fa fa-openid"></span> 
{{attribute.name}}</div>
               </td>
@@ -296,7 +170,7 @@
   </div>
 
   <!-- New identity card -->
-  <div class="card identity-new" (click)="addIdentity()" *ngIf="0 != 
identities.length && !isAddIdentity()">
+  <div class="card identity-new" [routerLink]="['/new-identity']" *ngIf="0 != 
identities.length">
     <div class="card-avatar card-img-top">
       <div class="card-avatar-character text-dark">
         <!--<div class="icon m-1 text-uppercase" 
[style.background-color]="intToRGB(identity.pubkey)">{{ 
identity.name[0]}}</div>-->
@@ -315,35 +189,4 @@
   </div>
 </div>
 
-<!-- Identity creation -->
-<div *ngIf="isAddIdentity()" class="m-2 card" style="text-align:center;">
-  <div class="card-avatar card-img-top">
-    <div class="card-avatar-character text-dark">
-      Add Identity        
-    </div>
-  </div>
-  <!-- Invalid input -->
-  <div *ngIf="'' !== newIdentity.name && !canSave() && !isDuplicate()" 
class="alert alert-danger alert-dismissible fade show" role="alert">
-    Only Alphanumeric input. No spaces or special characters allowed.
-  </div>
-  <!--Identity already exists -->  
-  <div *ngIf="isDuplicate()" class="alert alert-warning alert-dismissible fade 
show" role="alert"> 
-    An identity with this username already exists.
-  </div>
-  <!-- Input text -->
-  <div *ngIf="'' === newIdentity.name || canSave()" class="alert 
alert-secondary alert-dismissible fade show" role="alert">
-    Enter a username for your new identity
-  </div>
-  <div class="card-body">
-    <input [class.text-danger]="'' !== newIdentity.name && !canSave()" 
style="text-align: center; border: 1px solid #111;" 
(keyup.enter)="saveIdentity()" pattern="^[a-zA-Z0-9-]+" placeholder="Username" 
title="Only Alphanumeric input. No spaces or special characters allowed." 
class="mr-2" [(ngModel)]="newIdentity.name" autofocus>
-    <br/>
-    <br/>
-    <button [disabled]="!canSave()" [style.inactive]="!canSave()"  class="-1 
btn btn-primary" (click)="saveIdentity()">
-      <span class="fa fa-save"></span> Save
-    </button>
-    <button class="m-1 btn btn-danger" (click)="cancelAddIdentity()">
-      <span class="fa fa-close"></span> Cancel
-    </button>
-  </div>
-</div>
 
diff --git a/src/app/identity-list/identity-list.component.ts 
b/src/app/identity-list/identity-list.component.ts
index 8417c1f..b951fc2 100644
--- a/src/app/identity-list/identity-list.component.ts
+++ b/src/app/identity-list/identity-list.component.ts
@@ -26,16 +26,9 @@ export class IdentityListComponent implements OnInit {
   tickets: any;
   clientName: any;
   identities: Identity[];
-  newIdentity: Identity;
-  newAttribute: Attribute;
-  identityInEdit: Identity;
-  identityInEditName: string;
   identityNameMapper: any;
-  showTicketsIdentity: Identity;
   showConfirmDelete: any;
-  showConfirmRevoke: any;
   connected: any;
-  ticketAttributeMapper: any;
   modalOpened: any;
   clientNameFound: any;
   errorInfos: any;
@@ -54,17 +47,13 @@ export class IdentityListComponent implements OnInit {
     this.tickets = {};
     this.identities = [];
     this.showConfirmDelete = null;
-    this.showConfirmRevoke = null;
-    this.newAttribute = new Attribute('', '', '', 'STRING');
     this.requestedAttributes = {};
     this.missingAttributes = {};
     this.clientName = '-';
     this.connected = false;
-    this.ticketAttributeMapper = {};
     this.modalOpened = false;
     this.oidcService.parseRouteParams(this.route.snapshot.queryParams);
     this.getClientName();
-    this.identityInEditName = '';
     this.identityNameMapper = {};
     this.updateIdentities();
     this.errorInfos = [];
@@ -73,12 +62,9 @@ export class IdentityListComponent implements OnInit {
 
   confirmDelete(identity) { this.showConfirmDelete = identity; }
 
-  confirmRevoke(ticket) { this.showConfirmRevoke = ticket; }
 
   hideConfirmDelete() { this.showConfirmDelete = null; }
 
-  hideConfirmRevoke() { this.showConfirmRevoke = null; }
-
   getClientName() {
     this.clientNameFound = undefined;
     this.clientName = this.oidcService.getClientId();
@@ -120,73 +106,6 @@ export class IdentityListComponent implements OnInit {
     return hash;
   }
 
-  isAddIdentity() { return null != this.newIdentity; }
-
-  isDuplicate() {
-    for (let i = 0; i < this.identities.length; i++) {
-      if (this.identities[i].name === this.newIdentity.name) {
-        return true;
-      }
-    }
-  }
-
-  canSave() {
-    if (this.newIdentity.name == null) {
-      return false;
-    }
-    if (this.newIdentity.name === '') {
-      return false;
-    }
-    if (!/^[a-zA-Z0-9-]+$/.test(this.newIdentity.name)) {
-      return false;
-    }
-    if (this.isDuplicate()) {
-      return false;
-    }
-    return true;
-  }
-
-  addIdentity() { this.newIdentity = new Identity('', ''); }
-
-  editIdentity(identity) {
-    this.identityInEdit = identity;
-    this.showTicketsIdentity = null;
-  }
-
-  isInEdit(identity) { return this.identityInEdit === identity; }
-
-  saveIdentityAttributes(identity) {
-    this.storeAttributes(identity)
-      .pipe(
-        finalize(() => {
-          this.identityInEdit = null;
-          this.newAttribute.name = '';
-          this.newAttribute.value = '';
-          this.newAttribute.type = 'STRING';
-        }))
-      .subscribe(res => {
-        //FIXME success dialog/banner
-        this.identityInEdit = null;
-        this.updateAttributes(identity);
-      },
-      err => {
-        console.log(err);
-        this.errorInfos.push("Failed to update identity ``" +  
this.identityInEdit.name + "''");
-      });
-  }
-
-  deleteAttribute(attribute) {
-    this.reclaimService.deleteAttribute(this.identityInEdit, attribute)
-      .subscribe(res => {
-        //FIXME info dialog
-        this.updateAttributes(this.identityInEdit);
-      },
-      err => {
-        this.errorInfos.push("Failed to delete attribute ``" + attribute.name 
+ "''");
-        console.log(err);
-      });
-  }
-
   getMissingAttributes(identity) {
     const scopes = this.getScopes();
     let i;
@@ -205,74 +124,6 @@ export class IdentityListComponent implements OnInit {
     }
   }
 
-  private mapAudience(ticket) {
-    this.gnsService.getClientName(ticket.audience).subscribe(records => {
-      for (let i = 0; i < records.data.length; i++) {
-        if (records.data[i].record_type !== 'RECLAIM_OIDC_CLIENT') {
-          continue;
-        }
-        this.identityNameMapper[ticket.audience] = records.data[i].value;
-        break;
-      }
-    });
-  }
-
-  private mapAttributes(identity, ticket) {
-    this.namestoreService.getNames(identity).subscribe(names => {
-      this.ticketAttributeMapper[ticket.audience] = [];
-      names = names.filter(name => name.record_name === 
ticket.rnd.toLowerCase());
-      for (let i = 0; i < names.length; i++) {
-        names[i].data.forEach(record => {
-          if (record.record_type === 'RECLAIM_ATTR_REF') {
-            this.attributes[identity.pubkey]
-              .filter(attr => attr.id === record.value)
-              .map(attr => {
-                this.ticketAttributeMapper[ticket.audience].push(attr.name);
-              });
-          }
-        });
-      }
-    });
-  }
-
-  private updateTickets(identity) {
-    this.reclaimService.getTickets(identity).subscribe(tickets => {
-      this.tickets[identity.pubkey] = [];
-      if (tickets === null) {
-        return;
-      }
-      this.tickets[identity.pubkey] = tickets;
-      tickets.forEach(ticket => {
-        this.mapAudience(ticket);
-        this.mapAttributes(identity, ticket);
-      });
-    },
-    err => {
-      this.errorInfos.push("Unable to retrieve tickets for identity ``" + 
identity.name + "''");
-      console.log(err);
-    });
-  }
-
-  toggleShowTickets(identity) {
-    if (this.showTicketsIdentity === identity) {
-      this.showTicketsIdentity = null;
-      return;
-    }
-    this.showTicketsIdentity = identity;
-  }
-
-  revokeTicket(identity, ticket) {
-    this.reclaimService.revokeTicket(ticket).subscribe(
-      result => {
-        this.updateAttributes(identity);
-      },
-      err => {
-        this.errorInfos.push("Unable to revoke ticket.");
-        console.log(err);
-      });
-  }
-
-
   private updateAttributes(identity) {
     this.reclaimService.getAttributes(identity).subscribe(attributes => {
       this.attributes[identity.pubkey] = [];
@@ -289,7 +140,6 @@ export class IdentityListComponent implements OnInit {
         }
       }
       this.getMissingAttributes(identity);
-      this.updateTickets(identity);
     },
     err => {
       this.errorInfos.push("Error retrieving attributes for ``" + 
identity.name + "''");
@@ -297,72 +147,10 @@ export class IdentityListComponent implements OnInit {
     });
   }
 
-  private storeAttributes(identity) {
-    const promises = [];
-    let i;
-    if (undefined !== this.missingAttributes[identity.pubkey]) {
-      for (i = 0; i < this.missingAttributes[identity.pubkey].length; i++) {
-        if (this.missingAttributes[identity.pubkey][i].value === '') {
-          continue;
-        }
-        promises.push(from(this.reclaimService.addAttribute(
-          identity, this.missingAttributes[identity.pubkey][i])));
-      }
-    }
-    if (undefined !== this.attributes[identity.pubkey]) {
-      for (i = 0; i < this.attributes[identity.pubkey].length; i++) {
-        promises.push(
-          from(this.reclaimService.addAttribute(identity, 
this.attributes[identity.pubkey][i])));
-      }
-    }
-    if (this.newAttribute.value !== '') {
-      promises.push(from(this.reclaimService.addAttribute(identity, 
this.newAttribute)));
-    }
-
-    return forkJoin(promises);
-  }
-
-  addAttribute() {
-    this.storeAttributes(this.identityInEdit)
-      .pipe(
-        finalize(() => {
-          this.newAttribute.name = '';
-          this.newAttribute.value = '';
-          this.newAttribute.type = 'STRING';
-          this.updateAttributes(this.identityInEdit);
-        }))
-      .subscribe(res => {
-        console.log(res);
-      },
-      err => {
-        console.log(err);
-        this.errorInfos.push("Failed to update identity ``" +  
this.identityInEdit.name + "''");
-        EMPTY
-      });
-  }
-
-  cancelAddIdentity() { this.newIdentity = null; }
-
-  saveIdentity() {
-    if (!this.canSave()) {
-      return;
-    }
-    this.identityInEditName = this.newIdentity.name;
-    this.identityService.addIdentity(this.newIdentity)
-      .subscribe(res => {
-        this.newIdentity.name = '';
-        this.updateIdentities();
-        this.cancelAddIdentity();
-      },
-      err => {
-        this.errorInfos.push("Failed adding new identity ``" + 
this.newIdentity.name + "''");
-        console.log(err);
-      });
-  }
-
+  
+  
   deleteIdentity(identity) {
     this.showConfirmDelete = false;
-    this.identityInEdit = null;
     this.identityService.deleteIdentity(identity.pubkey)
       .subscribe(res => {
         this.updateIdentities();
@@ -414,65 +202,10 @@ export class IdentityListComponent implements OnInit {
     return this.oidcService.inOpenIdFlow();
   }
 
-  canAddAttribute(identity, attribute) {
-    if ((attribute.name === '') || (attribute.value === '')) {
-      return false;
-    }
-    if (attribute.name.indexOf(' ') >= 0) {
-      return false;
-    }
-    return !this.isInConflict(identity, attribute);
-  }
-
-  attributeNameValid(identity, attribute) {
-    if (attribute.name === '' && attribute.value === '') {
-      return true;
-    }
-    if (attribute.name.indexOf(' ') >= 0) {
-      return false;
-    }
-    if (!/^[a-zA-Z0-9-]+$/.test(attribute.name)) {
-      return false;
-    }
-    return !this.isInConflict(identity, attribute);
-  }
-
-  attributeValueValid(attribute) {
-    if (attribute.value === '') {
-      return attribute.name === '';
-    }
-    return true;
-  }
-
-  canSaveIdentity(identity) {
-    if (this.canAddAttribute(identity, this.newAttribute)) {
-      return true;
-    }
-    return ((this.newAttribute.name === '') &&
-      (this.newAttribute.value === '')) &&
-      !this.isInConflict(identity, this.newAttribute);
-  }
-
-  isInConflict(identity, attribute) {
-    let i;
-    if (undefined !== this.missingAttributes[identity.pubkey]) {
-      for (i = 0; i < this.missingAttributes[identity.pubkey].length; i++) {
-        if (attribute.name ===
-          this.missingAttributes[identity.pubkey][i].name) {
-          return true;
-        }
-      }
-    }
-    if (undefined !== this.attributes[identity.pubkey]) {
-      for (i = 0; i < this.attributes[identity.pubkey].length; i++) {
-        if (attribute.name === this.attributes[identity.pubkey][i].name) {
-          return true;
-        }
-      }
-    }
-    return false;
-  }
-
+  
+  
+  
+  
   getScopes() { return this.oidcService.getScope(); }
 
   getScopesPretty() { return this.getScopes().join(', '); }
@@ -488,7 +221,7 @@ export class IdentityListComponent implements OnInit {
   getMissingPretty(identity) { return this.getMissing(identity).join(', '); }
 
   canAuthorize(identity) {
-    return this.inOpenIdFlow() && !this.isInEdit(identity);
+    return this.inOpenIdFlow();
   }
 
   isRequested(identity, attribute) {
@@ -526,10 +259,6 @@ export class IdentityListComponent implements OnInit {
       for (i = 0; i < identities.length; i++) {
         this.identityNameMapper[identities[i].pubkey] = identities[i].name;
         this.identities.push(identities[i]);
-        if (this.identityInEditName === identities[i].name) {
-          this.editIdentity(this.identities[this.identities.length - 1]);
-          this.identityInEditName = '';
-        }
       }
 
       identities.forEach(identity => {
@@ -557,6 +286,6 @@ export class IdentityListComponent implements OnInit {
   }
 
   canSearch() {
-    return this.isConnected() && 0 != this.identities.length && 
!this.isAddIdentity() && (null == this.identityInEdit);
+    return this.isConnected() && 0 != this.identities.length;
   }
 }
diff --git a/src/app/new-identity/new-identity.component.css 
b/src/app/new-identity/new-identity.component.css
new file mode 100644
index 0000000..e69de29
diff --git a/src/app/new-identity/new-identity.component.html 
b/src/app/new-identity/new-identity.component.html
new file mode 100644
index 0000000..4e36507
--- /dev/null
+++ b/src/app/new-identity/new-identity.component.html
@@ -0,0 +1,31 @@
+<!-- Identity creation -->
+<div class="m-2 card" style="text-align:center;">
+  <div class="card-avatar card-img-top">
+    <div class="card-avatar-character text-dark">
+      Add Identity        
+    </div>
+  </div>
+  <!-- Invalid input -->
+  <div *ngIf="'' !== newIdentity.name && !canSave() && !isDuplicate()" 
class="alert alert-danger alert-dismissible fade show" role="alert">
+    Only Alphanumeric input. No spaces or special characters allowed.
+  </div>
+  <!--Identity already exists -->  
+  <div *ngIf="isDuplicate()" class="alert alert-warning alert-dismissible fade 
show" role="alert"> 
+    An identity with this username already exists.
+  </div>
+  <!-- Input text -->
+  <div *ngIf="'' === newIdentity.name || canSave()" class="alert 
alert-secondary alert-dismissible fade show" role="alert">
+    Enter a username for your new identity
+  </div>
+  <div class="card-body">
+    <input [class.text-danger]="'' !== newIdentity.name && !canSave()" 
style="text-align: center; border: 1px solid #111;" 
(keyup.enter)="saveIdentity()" pattern="^[a-zA-Z0-9-]+" placeholder="Username" 
title="Only Alphanumeric input. No spaces or special characters allowed." 
class="mr-2" [(ngModel)]="newIdentity.name" autofocus>
+    <br/>
+    <br/>
+    <button [disabled]="!canSave()" [style.inactive]="!canSave()"  class="-1 
btn btn-primary" (click)="saveIdentity()">
+      <span class="fa fa-save"></span> Save
+    </button>
+    <button class="m-1 btn btn-danger" (click)="cancelAddIdentity()">
+      <span class="fa fa-close"></span> Cancel
+    </button>
+  </div>
+</div>
diff --git a/src/app/new-identity/new-identity.component.ts 
b/src/app/new-identity/new-identity.component.ts
new file mode 100644
index 0000000..bf1a87e
--- /dev/null
+++ b/src/app/new-identity/new-identity.component.ts
@@ -0,0 +1,83 @@
+import { Component, OnInit } from '@angular/core';
+import { Router } from '@angular/router';
+import { Identity } from '../identity';
+import { IdentityService } from '../identity.service';
+
+@Component({
+  selector: 'app-new-identity',
+  templateUrl: './new-identity.component.html',
+  styleUrls: ['./new-identity.component.css']
+})
+export class NewIdentityComponent implements OnInit {
+
+  newIdentity: Identity;
+  identities: Identity[];
+
+  constructor(private identityService: IdentityService,
+              private router: Router) { }
+
+  ngOnInit() {
+    this.identities = [];
+    this.newIdentity = new Identity('','');
+  }
+
+  private updateIdentities() {
+    this.identityService.getIdentities().subscribe(identities => {
+      this.identities = [];
+      let i;
+      for (i = 0; i < identities.length; i++) {
+        this.identities.push(identities[i]);
+      }
+    },
+    error => {
+      console.log(error);
+      //this.openModal('GnunetInfo');
+      //this.connected = false;
+    });
+  }
+
+  cancelAddIdentity() {
+    this.newIdentity.name = '';
+    this.router.navigate(['/']);
+  }
+
+  isDuplicate() {
+    for (let i = 0; i < this.identities.length; i++) {
+      if (this.identities[i].name === this.newIdentity.name) {
+        return true;
+      }
+    }
+  }
+
+  canSave() {
+    if (this.newIdentity.name == null) {
+      return false;
+    }
+    if (this.newIdentity.name === '') {
+      return false;
+    }
+    if (!/^[a-zA-Z0-9-]+$/.test(this.newIdentity.name)) {
+      return false;
+    }
+    if (this.isDuplicate()) {
+      return false;
+    }
+    return true;
+  }
+
+  saveIdentity() {
+    if (!this.canSave()) {
+      return;
+    }
+    this.identityService.addIdentity(this.newIdentity)
+      .subscribe(res => {
+      this.newIdentity.name = '';
+      this.router.navigate(['/']);
+    },
+    err => {
+      //this.errorInfos.push("Failed adding new identity ``" + 
this.newIdentity.name + "''");
+      console.log(err);
+    });
+  }
+
+}
diff --git a/src/app/open-id.service.ts b/src/app/open-id.service.ts
index 6838784..5a85f35 100644
--- a/src/app/open-id.service.ts
+++ b/src/app/open-id.service.ts
@@ -47,12 +47,6 @@ export class OpenIdService {
   }
 
   inOpenIdFlow(): any {
-    if (this.params['redirect_uri'] !== undefined) {
-      console.log ('In OIDC flow');
-    } else {
-      console.log ('Not in OIDC flow');
-      console.log (this.params);
-    }
     return this.params['redirect_uri'] !== undefined;
   }
 

-- 
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]