Skip to content

Commit

Permalink
Merge pull request #513 from openziti/512-jwt-signers-page
Browse files Browse the repository at this point in the history
New JWT Signers List Page
  • Loading branch information
rgallettonf authored Oct 7, 2024
2 parents b4f88ea + 5f04ed1 commit 94271bf
Show file tree
Hide file tree
Showing 18 changed files with 1,103 additions and 23 deletions.
14 changes: 12 additions & 2 deletions projects/app-ziti-console/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ import {
ServiceEdgeRouterPoliciesPageComponent,
ServiceEdgeRouterPolicyFormComponent,
TerminatorsPageComponent,
TerminatorFormComponent
TerminatorFormComponent,
JwtSignersPageComponent,
JwtSignerFormComponent
} from "ziti-console-lib";
import {environment} from "./environments/environment";
import {URLS} from "./app-urls.constants";
Expand Down Expand Up @@ -88,8 +90,16 @@ const routes: Routes = [
},
{
path: 'jwt-signers',
component: ZacWrapperComponent,
component: JwtSignersPageComponent,
canActivate: mapToCanActivate([AuthenticationGuard]),
canDeactivate: [DeactivateGuardService],
runGuardsAndResolvers: 'always',
},
{
path: 'jwt-signers/:id',
component: JwtSignerFormComponent,
canActivate: mapToCanActivate([AuthenticationGuard]),
canDeactivate: [DeactivateGuardService],
runGuardsAndResolvers: 'always',
},
{
Expand Down
2 changes: 1 addition & 1 deletion projects/ziti-console-lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openziti/ziti-console-lib",
"version": "0.5.1",
"version": "0.6.0",
"repository": {
"type": "git",
"url": "https://github.com/openziti/ziti-console"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
background-color: var(--navigation);
padding: 15px 15px;
border-radius: 10px;
gap: 15px;
gap: var(--marginMedium);
height: 100%;
position: relative;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<div class="projectable-form-wrapper"
(keyup.enter)="save($event)"
(keyup.escape)="closeModal(false)"
tabindex="0"
>
<lib-form-header
[data]="formData"
[title]="(formData.id ? 'JWT Signer Details' : 'Create JWT Signer')"
[moreActions]="formData.moreActions"
(actionRequested)="headerActionRequested($event)"
[(formView)]="formView"
[saveDisabled]="svc.saveDisabled || formDataInvalid"
></lib-form-header>
<div class="jwt-signer-form-container projectable-form-container">
<div class="projectable-form-main-column form-group-row" [hidden]="formView !== 'simple'">
<div class="form-group-column three-fifths">
<lib-form-field-container
[title]="'Name'"
[label]="'Required'"
>
<input class="form-field-input read-only" [(ngModel)]="formData.name" [ngClass]="{error: errors['name']}" placeholder="Name this JWT Signer"/>
</lib-form-field-container>
<lib-form-field-container
[layout]="'column'"
[showHeader]="false"
>
<div class="form-field-label-container">
<div class="form-field-header">
<div class="form-field-title-container">
<span class="form-field-title">Issuer</span>
<div
class="form-field-info infoicon"
matTooltip="The &quot;issuer&quot; field on the JWT Signer must match the &quot;iss&quot; field on the JWT"
matTooltipPosition="below"
></div>
</div>
<span class="form-field-label" >Required</span>
</div>
<input class="form-field-input" placeholder="Enter issuer" [(ngModel)]="formData.issuer" [ngClass]="{error: errors['issuer']}"/>
</div>
<div class="form-field-label-container">
<div class="form-field-title-container">
<span class="form-field-title">Claims Property</span>
<div
class="form-field-info infoicon"
matTooltip="The &quot;claimsProperty&quot; must match the &quot;id&quot; field on a ziti identity (or externalId if &quot;Use External ID&quot; is enabled)"
matTooltipPosition="below"
></div>
</div>
<input class="form-field-input" placeholder="Enter claims property, defaults to &quot;sub&quot;" [(ngModel)]="formData.claimsProperty"/>
</div>
<div class="form-field-label-container">
<div class="form-field-title-container">
<span class="form-field-title">Audience</span>
<div
class="form-field-info infoicon"
matTooltip="The &quot;audience&quot; field on the JWT Signer must match the &quot;aud&quot; field on the JWT"
matTooltipPosition="below"
></div>
</div>
<input class="form-field-input" placeholder="Enter audience" [(ngModel)]="formData.audience"/>
</div>
<div class="form-field-label-container">
<div class="form-field-title-container">
<span class="form-field-title">External Auth Url</span>
<div
class="form-field-info infoicon"
matTooltip="Unauthenticated clients can enumerate External JWT Signers that have an &quot;externalAuthUrl&quot; property. Clients will receive the name of the External JWT Signer and the &quot;externalAuthUrl&quot; only. This information can allow clients to initiate client authentication to the target identity provider."
matTooltipPosition="below"
></div>
</div>
<input class="form-field-input" placeholder="Enter external auth URL" [(ngModel)]="formData.externalAuthUrl"/>
</div>
</lib-form-field-container>
<lib-form-field-container
[showHeader]="false"
[layout]="'row'"
>
<div class="config-item">
<div class="config-container toggle-container">
<div class="config-container-label">ENABLED</div>
<div
(click)="toggleEnabled()"
[ngClass]="{ on: formData.enabled }"
class="toggle"
>
<span [hidden]="!formData.enabled" class="on-label">YES</span>
<span [hidden]="formData.enabled" class="off-label">NO</span>
<div class="switch"></div>
</div>
</div>
</div>

<div class="config-item">
<div class="config-container toggle-container">
<div class="config-container-label">Use External ID</div>
<div
(click)="toggleUseExternalId()"
[ngClass]="{ on: formData.useExternalId }"
class="toggle"
>
<span [hidden]="!formData.useExternalId" class="on-label">YES</span>
<span [hidden]="formData.useExternalId" class="off-label">NO</span>
<div class="switch"></div>
</div>
</div>
</div>
</lib-form-field-container>
<lib-form-field-toggle [(toggleOn)]="showMore" (toggleOnChange)="showMoreChanged($event)" style="margin: 0px 10px"></lib-form-field-toggle>
<div [hidden]="!showMore" class="form-group-column">
<lib-form-field-container
[title]="'Custom Tags'"
[label]="'OPTIONAL'"
class="form-field-advanced"
>
<lib-custom-tags [(tags)]="formData.tags"></lib-custom-tags>
</lib-form-field-container>
</div>
</div>
<div class="form-group-column two-fifths">
<lib-form-field-container
[title]="'Certificate Definition'"
[label]="'REQUIRED'"
>
<div class="form-field-input-group">
<div class="form-field-label-container select-file-label-container">
<div class="form-field-header">
<div class="form-field-title-container">
<span class="form-field-title">PEM</span>
</div>
<span class="select-file-button" (click)="openFileSelect($event)">
Select File
<div class="spinner" *ngIf="fileSelectOpening"></div>
</span>
<input #fileSelect type="file" style="display:none" (change)="selectPemFile($event)">
</div>
<textarea placeholder="Paste pem contents or select file" [(ngModel)]="formData.certPem" [ngClass]="{error: errors['certPem']}"></textarea>
</div>
<div class="form-field-label-container">
<div class="form-field-header">
<div class="form-field-title-container">
<span class="form-field-title">KID</span>
</div>
<span class="form-field-label" >Optional</span>
</div>
<input class="form-field-input" placeholder="Enter KID" [(ngModel)]="formData.kid"/>
</div>
</div>
</lib-form-field-container>
<lib-form-field-container
[title]="'JWKS Endpoint'"
[label]="'Optional'"
>
<input class="form-field-input read-only" placeholder="Enter endpoint URL" [(ngModel)]="formData.jwksEndpoint"/>
</lib-form-field-container>
<lib-form-field-container
[title]="'API Calls'"
[headerActions]="apiOptions"
(actionRequested)="apiActionRequested($event)"
[class]="'api-data-no-wrap'"
>
<div class="form-row">
<input class="form-field-input" [value]="apiCallURL"/>
<div class="icon-copy copy" (click)="copyToClipboard(apiCallURL)"></div>
</div>
<lib-json-view *ngIf="formData" [(data)]="apiData" [readOnly]="true" [showCopy]="true"></lib-json-view>
</lib-form-field-container>
</div>
</div>
<div class="form-group-column" *ngIf="formView === 'raw'">
<lib-json-view *ngIf="formData" [(data)]="formData"></lib-json-view>
</div>
</div>
</div>
<lib-loading-indicator *ngIf="isLoading" [isLoading]="isLoading"></lib-loading-indicator>
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
.jwt-signer-form-container {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
align-items: center;
gap: var(--gapXL);

.select-file-button {
padding-left: var(--paddingMedium);
padding-right: var(--paddingMedium);
height: 25px;
width: fit-content;
white-space: nowrap;
display: flex;
align-items: center;
justify-content: center;
font-weight: 600;
font-size: 14px;
background: var(--primary);
border-style: solid;
border-width: 1px;
border-color: var(--stroke);
color: var(--white);
cursor: pointer;
border-radius: var(--inputBorderRadius);
gap: var(--marginMedium);

&:hover {
filter: brightness(.8);
}
&:active {
filter: grayscale(1);
transform: translateY(1px);
}

.spinner {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
background: transparent;
border-top: 2px solid white;
border-right: 2px solid white;
border-bottom: 2px solid transparent;
border-left: 2px solid transparent;
-webkit-animation: loading 0.5s infinite linear;
animation: loading 0.5s infinite linear;
}
}

.select-file-label-container {
gap: var(--marginMedium);
}
}

::ng-deep .jwt-signer-form-container {
select,
input {
&:disabled {
opacity: 0.75 !important;
cursor: text;
background-color: var(--stroke) !important;
}
}
}

::ng-deep .api-data-no-wrap{
.jse-text-mode {
width: 100%;
.cm-editor {
width: 100%;
.cm-scroller {
width: 100%;
.cm-content {
width: 100%;
overflow: auto;
.ͼr {
white-space: nowrap;
}
}
}
}
}
}
Loading

0 comments on commit 94271bf

Please sign in to comment.