Skip to content

Commit

Permalink
refactor: Refactor user.model for improved type safety
Browse files Browse the repository at this point in the history
Previously `User` instances had just had an object field named `userModel` that contained all user details with none of the inner fields defined.
Removed the `userModel` field and explicitly defined the fields directly on `User`
  • Loading branch information
jrassa committed Mar 4, 2024
1 parent 85b061c commit 2473096
Show file tree
Hide file tree
Showing 26 changed files with 162 additions and 173 deletions.
10 changes: 5 additions & 5 deletions src/app/core/admin/user/admin-users.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ export class AdminUsersService {
.pipe(
map((results: PagingResults) => {
if (null != results && Array.isArray(results.elements)) {
results.elements = results.elements.map((element: any) =>
new User().setFromUserModel(element)
results.elements = results.elements.map(
(element: any) => new User(element)
);
}
return results;
Expand All @@ -68,17 +68,17 @@ export class AdminUsersService {
}

create(user: User) {
return this.http.post('api/admin/user', user.userModel);
return this.http.post('api/admin/user', user);
}

read(userId: string) {
return this.http
.get(`api/admin/user/${userId}`)
.pipe(map((userRaw: any) => new User().setFromUserModel(userRaw)));
.pipe(map((userRaw: any) => new User(userRaw)));
}

update(user: User): Observable<any> {
return this.http.post(`api/admin/user/${user.userModel._id}`, user.userModel);
return this.http.post(`api/admin/user/${user._id}`, user);
}

redirectError(error: unknown) {
Expand Down
39 changes: 19 additions & 20 deletions src/app/core/admin/user/list-users/admin-list-users.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -58,41 +58,41 @@ <h1 skipTo>Users</h1>
<ng-container cdkColumnDef="id">
<th cdk-header-cell *cdkHeaderCellDef>ID</th>
<td cdk-cell *cdkCellDef="let user">
{{ user.userModel._id }}
{{ user._id }}
</td>
</ng-container>
<ng-container cdkColumnDef="name">
<th asy-sort-header cdk-header-cell *cdkHeaderCellDef>Name</th>
<td class="text-nowrap" cdk-cell *cdkCellDef="let user">
<a
class="text-decoration-underline"
[routerLink]="['/admin/user', user.userModel._id]"
>{{ user.userModel.name }}</a
[routerLink]="['/admin/user', user._id]"
>{{ user.name }}</a
>
</td>
</ng-container>
<ng-container cdkColumnDef="username">
<th asy-sort-header cdk-header-cell *cdkHeaderCellDef>Username</th>
<td class="text-nowrap" cdk-cell *cdkCellDef="let user">
{{ user.userModel.username }}
{{ user.username }}
</td>
</ng-container>
<ng-container cdkColumnDef="organization">
<th cdk-header-cell *cdkHeaderCellDef>Organization</th>
<td cdk-cell *cdkCellDef="let user">
{{ user.userModel.organization }}
{{ user.organization }}
</td>
</ng-container>
<ng-container cdkColumnDef="email">
<th cdk-header-cell *cdkHeaderCellDef>Email</th>
<td cdk-cell *cdkCellDef="let user">
{{ user.userModel.email }}
{{ user.email }}
</td>
</ng-container>
<ng-container cdkColumnDef="phone">
<th cdk-header-cell *cdkHeaderCellDef>Phone</th>
<td cdk-cell *cdkCellDef="let user">
{{ user.userModel.phone }}
{{ user.phone }}
</td>
</ng-container>
<ng-container cdkColumnDef="acceptedEua">
Expand All @@ -101,9 +101,9 @@ <h1 skipTo>Users</h1>
<div
class="text-nowrap"
container="body"
tooltip="{{ user.userModel.acceptedEua | utcDate }}"
tooltip="{{ user.acceptedEua | utcDate }}"
>
{{ user.userModel.acceptedEua | agoDate: false }}
{{ user.acceptedEua | agoDate: false }}
</div>
</td>
</ng-container>
Expand All @@ -113,34 +113,34 @@ <h1 skipTo>Users</h1>
<div
class="text-nowrap"
container="body"
tooltip="{{ user.userModel.lastLogin | utcDate }}"
tooltip="{{ user.lastLogin | utcDate }}"
>
{{ user.userModel.lastLogin | agoDate: false }}
{{ user.lastLogin | agoDate: false }}
</div>
</td>
</ng-container>
<ng-container cdkColumnDef="created">
<th asy-sort-header cdk-header-cell *cdkHeaderCellDef>Created</th>
<td class="text-nowrap" cdk-cell *cdkCellDef="let user">
{{ user.userModel.created | utcDate }}
{{ user.created | utcDate }}
</td>
</ng-container>
<ng-container cdkColumnDef="updated">
<th cdk-header-cell *cdkHeaderCellDef>Updated</th>
<td class="text-nowrap" cdk-cell *cdkCellDef="let user">
{{ user.userModel.updated | utcDate }}
{{ user.updated | utcDate }}
</td>
</ng-container>
<ng-container cdkColumnDef="externalRoles">
<th cdk-header-cell *cdkHeaderCellDef>External Roles</th>
<td class="hide-overflow" cdk-cell *cdkCellDef="let user">
{{ user.userModel.externalRoles | join: ', ' }}
{{ user.externalRoles | join: ', ' }}
</td>
</ng-container>
<ng-container cdkColumnDef="externalGroups">
<th cdk-header-cell *cdkHeaderCellDef>External Groups</th>
<td class="hide-overflow" cdk-cell *cdkCellDef="let user">
{{ user.userModel.externalGroups | join: ', ' }}
{{ user.externalGroups | join: ', ' }}
</td>
</ng-container>
<ng-container cdkColumnDef="roles">
Expand All @@ -154,10 +154,9 @@ <h1 skipTo>Users</h1>
class="user-role text-nowrap"
[ngClass]="{
'user-role-external':
user.userModel.localRoles &&
!user.userModel.localRoles[role.role]
user.localRoles && !user.localRoles[role.role]
}"
*ngIf="user.userModel.roles?.[role.role]"
*ngIf="user.roles?.[role.role]"
>
{{ role.label }}
</div>
Expand All @@ -168,7 +167,7 @@ <h1 skipTo>Users</h1>
<th cdk-header-cell *cdkHeaderCellDef>Teams</th>
<td cdk-cell *cdkCellDef="let user">
<div class="cdk-cell-collapsible">
<div class="text-nowrap" *ngFor="let team of user.userModel.teams">
<div class="text-nowrap" *ngFor="let team of user.teams">
<a
class="text-decoration-underline"
[routerLink]="['/team', team._id]"
Expand Down Expand Up @@ -200,7 +199,7 @@ <h1 skipTo>Users</h1>
<a
class="dropdown-item"
cdkMenuItem
[routerLink]="['/admin/user', user.userModel._id]"
[routerLink]="['/admin/user', user._id]"
>
Edit
</a>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,13 +207,13 @@ export class AdminListUsersComponent implements OnDestroy, OnInit {
this.dialogService
.confirm(
'Delete user?',
`Are you sure you want to delete the user: <strong>"${user.userModel.name}"</strong>?<br/>This action cannot be undone.`,
`Are you sure you want to delete the user: <strong>"${user.name}"</strong>?<br/>This action cannot be undone.`,
'Delete'
)
.closed.pipe(
first(),
filter((result) => result?.action === DialogAction.OK),
switchMap(() => this.adminUsersService.removeUser(user.userModel._id)),
switchMap(() => this.adminUsersService.removeUser(user._id)),
catchError((error: unknown) => {
if (error instanceof HttpErrorResponse) {
this.alertService.addClientErrorAlert(error);
Expand Down
24 changes: 12 additions & 12 deletions src/app/core/admin/user/manage-user/manage-user.component.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<section *ngIf="user?.userModel">
<section>
<!-- Show a breadcrumb to the list users page -->
<a class="back-link" routerLink="/admin/users">
<span class="fa-solid fa-angle-double-left"></span> Back to Users
Expand Down Expand Up @@ -34,7 +34,7 @@ <h1 class="mb-4">
name="name"
type="text"
required
[(ngModel)]="user.userModel.name"
[(ngModel)]="user.name"
[disabled]="metadataLocked"
/>
</div>
Expand All @@ -48,7 +48,7 @@ <h1 class="mb-4">
name="username"
type="text"
required
[(ngModel)]="user.userModel.username"
[(ngModel)]="user.username"
[disabled]="metadataLocked"
/>
</div>
Expand All @@ -62,7 +62,7 @@ <h1 class="mb-4">
name="organization"
type="text"
required
[(ngModel)]="user.userModel.organization"
[(ngModel)]="user.organization"
[disabled]="metadataLocked"
/>
</div>
Expand All @@ -76,7 +76,7 @@ <h1 class="mb-4">
name="email"
type="email"
required
[(ngModel)]="user.userModel.email"
[(ngModel)]="user.email"
[disabled]="metadataLocked"
/>
</div>
Expand All @@ -99,7 +99,7 @@ <h2 class="pt-3">
name="password"
type="password"
autocomplete="off"
[(ngModel)]="user.userModel.password"
[(ngModel)]="user.password"
/>
</div>

Expand All @@ -113,7 +113,7 @@ <h2 class="pt-3">
name="password2"
type="password"
autocomplete="off"
[(ngModel)]="user.userModel.verifyPassword"
[(ngModel)]="user.verifyPassword"
/>
</div>
</ng-container>
Expand All @@ -129,7 +129,7 @@ <h2 class="pt-3">
id="bypassAC"
name="bypassAccessCheck"
type="checkbox"
[(ngModel)]="user.userModel.bypassAccessCheck"
[(ngModel)]="user.bypassAccessCheck"
/>
<label class="form-check-label" for="bypassAC">Bypass Access Check</label>
</div>
Expand All @@ -145,7 +145,7 @@ <h2 class="pt-3">
name="dn"
type="text"
disabled
[(ngModel)]="user.userModel.providerData.dn"
[(ngModel)]="user.providerData.dn"
/>
</div>

Expand All @@ -158,7 +158,7 @@ <h2 class="pt-3">
type="text"
disabled
rows="4"
>{{ user.userModel.externalRolesDisplay }}</textarea
>{{ user.externalRolesDisplay }}</textarea
>
</div>

Expand All @@ -171,7 +171,7 @@ <h2 class="pt-3">
type="text"
disabled
rows="4"
>{{ user.userModel.externalGroupsDisplay }}</textarea
>{{ user.externalGroupsDisplay }}</textarea
>
</div>
</ng-container>
Expand All @@ -190,7 +190,7 @@ <h2 class="pt-3">
id="role{{ role.role }}Cb"
name="role{{ role.role }}Cb"
type="checkbox"
[(ngModel)]="user.userModel.roles[role.role]"
[(ngModel)]="user.roles[role.role]"
/>
<label class="form-check-label" for="role{{ role.role }}Cb">{{
role.label
Expand Down
23 changes: 7 additions & 16 deletions src/app/core/admin/user/manage-user/manage-user.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { first } from 'rxjs/operators';
import { SystemAlertComponent } from '../../../../common/system-alert/system-alert.component';
import { SystemAlertService } from '../../../../common/system-alert/system-alert.service';
import { Role } from '../../../auth/role.model';
import { User } from '../../../auth/user.model';
import { EditUser } from '../../../auth/user.model';
import { ConfigService } from '../../../config.service';
import { AdminUsersService } from '../admin-users.service';

Expand All @@ -25,7 +25,7 @@ export class ManageUserComponent implements OnInit {
mode: 'create' | 'edit' = 'create';

@Input()
user: User;
user: EditUser;

proxyPki = false;
metadataLocked = false;
Expand All @@ -42,20 +42,11 @@ export class ManageUserComponent implements OnInit {

if (this.user) {
this.mode = 'edit';
if (null === this.user.userModel.roles) {
this.user.userModel.roles = {};
}
this.user.userModel.externalRolesDisplay =
this.user.userModel.externalRoles?.join('\n');
this.user.userModel.externalGroupsDisplay =
this.user.userModel.externalGroups?.join('\n');
this.user.userModel.providerData = {
dn: this.user.userModel.providerData?.dn
};
this.metadataLocked = this.proxyPki && !this.user.userModel.bypassAccessCheck;
this.user.externalRolesDisplay = this.user.externalRoles?.join('\n');
this.user.externalGroupsDisplay = this.user.externalGroups?.join('\n');
this.metadataLocked = this.proxyPki && !this.user.bypassAccessCheck;
} else {
this.user = new User();
this.user.userModel.roles = {};
this.user = new EditUser();
}

this.configService
Expand Down Expand Up @@ -86,7 +77,7 @@ export class ManageUserComponent implements OnInit {
}

private validatePassword(): boolean {
if (this.user.userModel.password === this.user.userModel.verifyPassword) {
if (this.user.password === this.user.verifyPassword) {
return true;
}

Expand Down
6 changes: 3 additions & 3 deletions src/app/core/audit/audit.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export class AuditService {
search: string,
paging: PagingOptions,
options: any
): Observable<PagingResults> {
): Observable<PagingResults<User>> {
return this.http
.post<PagingResults>(
'api/users/match',
Expand All @@ -61,8 +61,8 @@ export class AuditService {
.pipe(
map((results: PagingResults) => {
if (null != results && Array.isArray(results.elements)) {
results.elements = results.elements.map((element: any) =>
new User().setFromUserModel(element)
results.elements = results.elements.map(
(element: any) => new User(element)
);
}
return results;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class AuditActorFilterDirective implements OnInit {
this.typeaheadFilter.buildFilterFunc = this.buildFilter;
}

typeaheadSearch(term: string): Observable<any> {
typeaheadSearch(term: string) {
return this.auditService
.matchUser({}, term, new PagingOptions(), {})
.pipe(map((pagingResult) => pagingResult.elements));
Expand All @@ -32,7 +32,7 @@ export class AuditActorFilterDirective implements OnInit {
if (selectedValue) {
return {
['audit.actor._id']: {
$obj: selectedValue.userModel._id
$obj: selectedValue._id
}
};
}
Expand Down
6 changes: 3 additions & 3 deletions src/app/core/auth/authentication.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Injectable } from '@angular/core';

import { Observable } from 'rxjs';

import { User } from './user.model';
import { EditUser } from './user.model';

@Injectable({ providedIn: 'root' })
export class AuthenticationService {
Expand All @@ -13,8 +13,8 @@ export class AuthenticationService {
return this.http.post('api/auth/signin', { username, password });
}

signup(user: User): Observable<any> {
return this.http.post('api/auth/signup', user.userModel);
signup(user: EditUser): Observable<any> {
return this.http.post('api/auth/signup', user);
}

reloadCurrentUser(): Observable<any> {
Expand Down
Loading

0 comments on commit 2473096

Please sign in to comment.