finish api key management interface
This commit is contained in:
parent
a91363962a
commit
6b0504ec9c
|
@ -19,6 +19,7 @@ export class ApiKeyDbService {
|
|||
async createApiKey(userid: string): AsyncFailable<EApiKeyBackend<string>> {
|
||||
const apikey = new EApiKeyBackend<string>();
|
||||
apikey.user = userid;
|
||||
apikey.created = new Date();
|
||||
apikey.key = generateRandomString(32); // Might collide, probably not
|
||||
|
||||
/*
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import { EApiKeySchema } from 'picsur-shared/dist/entities/apikey.entity';
|
||||
import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
Entity,
|
||||
Column, Entity,
|
||||
ManyToOne,
|
||||
PrimaryColumn
|
||||
} from 'typeorm';
|
||||
|
@ -33,7 +31,7 @@ export class EApiKeyBackend<
|
|||
})
|
||||
user: T;
|
||||
|
||||
@CreateDateColumn({
|
||||
@Column({
|
||||
nullable: false,
|
||||
})
|
||||
created: Date;
|
||||
|
|
|
@ -35,6 +35,7 @@ const SystemRoleDefaultsTyped: {
|
|||
Permission.UserLogin,
|
||||
Permission.Settings,
|
||||
Permission.ImageUpload,
|
||||
Permission.ApiKey,
|
||||
],
|
||||
// Grant all permissions to admin
|
||||
admin: PermissionsList,
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
<mat-form-field appearance="outline" color="accent">
|
||||
<mat-label>{{ label }}</mat-label>
|
||||
<input matInput [value]="value" readonly="readonly" />
|
||||
<input
|
||||
matInput
|
||||
[value]="value"
|
||||
readonly="readonly"
|
||||
[type]="hidden ? 'password' : 'text'"
|
||||
/>
|
||||
<button
|
||||
*ngIf="showHideButton"
|
||||
mat-icon-button
|
||||
matSuffix
|
||||
[attr.aria-label]="'Hide'"
|
||||
(click)="toggleHide()"
|
||||
>
|
||||
<mat-icon>{{ hidden ? 'visibility_off' : 'visibility' }}</mat-icon>
|
||||
</button>
|
||||
<button mat-icon-button matSuffix [attr.aria-label]="'Copy'" (click)="copy()">
|
||||
<mat-icon>content_copy</mat-icon>
|
||||
</button>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { Clipboard } from '@angular/cdk/clipboard';
|
||||
import { Component, Input } from '@angular/core';
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
import { SnackBarType } from 'src/app/models/dto/snack-bar-type.dto';
|
||||
import { UtilService } from 'src/app/util/util-module/util.service';
|
||||
|
||||
|
@ -13,6 +13,12 @@ export class CopyFieldComponent {
|
|||
@Input() label: string = 'Loading...';
|
||||
@Input() value: string = 'Loading...';
|
||||
|
||||
@Input() showHideButton: boolean = false;
|
||||
@Input() hidden: boolean = false;
|
||||
|
||||
@Output('copy') onCopy = new EventEmitter<string>();
|
||||
@Output('hide') onHide = new EventEmitter<boolean>();
|
||||
|
||||
constructor(
|
||||
private readonly utilService: UtilService,
|
||||
private readonly clipboard: Clipboard,
|
||||
|
@ -21,6 +27,7 @@ export class CopyFieldComponent {
|
|||
public copy() {
|
||||
if (this.clipboard.copy(this.value)) {
|
||||
this.utilService.showSnackBar(`Copied ${this.label}!`, SnackBarType.Info);
|
||||
this.onCopy.emit(this.value);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -29,4 +36,9 @@ export class CopyFieldComponent {
|
|||
SnackBarType.Error,
|
||||
);
|
||||
}
|
||||
|
||||
public toggleHide() {
|
||||
this.hidden = !this.hidden;
|
||||
this.onHide.emit(this.hidden);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,24 +4,31 @@
|
|||
<ng-container matColumnDef="key">
|
||||
<mat-header-cell *matHeaderCellDef>Key</mat-header-cell>
|
||||
<mat-cell *matCellDef="let apikey">
|
||||
<copy-field label="Key" [value]="apikey.key"></copy-field>
|
||||
<copy-field
|
||||
label="Key"
|
||||
[value]="apikey.key"
|
||||
[hidden]="true"
|
||||
[showHideButton]="true"
|
||||
></copy-field>
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="created">
|
||||
<mat-header-cell class="d-none d-md-flex" *matHeaderCellDef>
|
||||
<mat-header-cell class="d-none d-lg-flex" *matHeaderCellDef>
|
||||
Created
|
||||
</mat-header-cell>
|
||||
<mat-cell class="d-none d-md-flex" *matCellDef="let apikey">{{
|
||||
apikey.created | amTimeAgo
|
||||
}}</mat-cell>
|
||||
<mat-cell class="d-none d-lg-flex" *matCellDef="let apikey">
|
||||
{{ apikey.created | amTimeAgo }}
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="last_used">
|
||||
<mat-header-cell *matHeaderCellDef>Last Used</mat-header-cell>
|
||||
<mat-cell *matCellDef="let apikey">{{
|
||||
apikey.last_used === null ? 'Never' : (apikey.last_used | amTimeAgo)
|
||||
}}</mat-cell>
|
||||
<mat-header-cell class="d-none d-sm-flex" *matHeaderCellDef>
|
||||
Last Used
|
||||
</mat-header-cell>
|
||||
<mat-cell class="d-none d-sm-flex" *matCellDef="let apikey">
|
||||
{{ apikey.last_used === null ? 'Never' : (apikey.last_used | amTimeAgo) }}
|
||||
</mat-cell>
|
||||
</ng-container>
|
||||
|
||||
<ng-container matColumnDef="actions">
|
||||
|
|
|
@ -4,6 +4,7 @@ mat-table {
|
|||
|
||||
.mat-column-actions {
|
||||
justify-content: end;
|
||||
flex-grow: .5;
|
||||
}
|
||||
|
||||
.mat-column-key {
|
||||
|
@ -11,7 +12,7 @@ mat-table {
|
|||
}
|
||||
|
||||
.mat-column-last_used {
|
||||
flex-grow: .5;
|
||||
flex-grow: 0.5;
|
||||
}
|
||||
|
||||
.icon-red {
|
||||
|
@ -20,4 +21,7 @@ mat-table {
|
|||
|
||||
copy-field {
|
||||
margin-top: 1rem;
|
||||
width: 100%;
|
||||
margin-right: 1rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue