Skip to content

Commit

Permalink
User Update
Browse files Browse the repository at this point in the history
  • Loading branch information
un33k committed Jun 11, 2021
1 parent dc227f3 commit 29d5956
Show file tree
Hide file tree
Showing 60 changed files with 1,310 additions and 288 deletions.
22 changes: 22 additions & 0 deletions angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,28 @@
}
}
}
},
"ngx-user": {
"projectType": "library",
"root": "libs/ngx-user",
"sourceRoot": "libs/ngx-user/src",
"prefix": "fullerstack",
"architect": {
"test": {
"builder": "@nrwl/jest:jest",
"outputs": ["coverage/libs/ngx-user"],
"options": {
"jestConfig": "libs/ngx-user/jest.config.js",
"passWithNoTests": true
}
},
"lint": {
"builder": "@nrwl/linter:eslint",
"options": {
"lintFilePatterns": ["libs/ngx-user/src/**/*.ts", "libs/ngx-user/src/**/*.html"]
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion apps/api/src/environments/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const appConfig: ConfigModuleOptions = {
};

const securityConfig: SecurityConfig = {
accessTokenExpiry: '15m',
accessTokenExpiry: '30s',
sessionTokenExpiry: '7d',
bcryptSaltOrRound: 2,
};
Expand Down
24 changes: 12 additions & 12 deletions apps/api/src/prisma/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ type Mutation {
authResetPasswordRequest(input: ChangePasswordRequestInput!): AuthStatusDto!
isEmailAvailable(email: String!): AuthStatusDto!

"""Privileged user update"""
userUpdate(input: UserUpdateAdvancedInput!): UserDto!

"""Update user's own info"""
userUpdateSelf(input: UserUpdateInput!): UserDto!
userSelfUpdate(input: UserSelfUpdateInput!): UserDto!

"""Privileged user update"""
userUpdate(input: UserUpdateInput!): UserDto!
}

"""Ascending or Descending direction for a given `orderBy` argument."""
Expand All @@ -70,7 +70,7 @@ enum Permission {

type Query {
"""Get other user info"""
user(input: UserUpdateAdvancedInput!): UserDto!
user(input: UserWhereByIdInput!): UserDto!

"""Get user's own info"""
userSelf: UserDto!
Expand Down Expand Up @@ -114,9 +114,6 @@ type UserDto {
permissions: [Permission!]
role: Role

"""Session version"""
sessionVersion: Int

"""Object's update time"""
updatedAt: DateTime!
username: String
Expand All @@ -142,7 +139,12 @@ enum UserOrderField {
username
}

input UserUpdateAdvancedInput {
input UserSelfUpdateInput {
firstName: String
lastName: String
}

input UserUpdateInput {
firstName: String
groupId: ID
id: ID!
Expand All @@ -157,8 +159,6 @@ input UserUpdateAdvancedInput {
role: Role
}

input UserUpdateInput {
firstName: String
input UserWhereByIdInput {
id: ID!
lastName: String
}
4 changes: 3 additions & 1 deletion apps/fullerstack/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { I18nService } from '@fullerstack/ngx-i18n';
import { LayoutService } from '@fullerstack/ngx-layout';
import { LoggerService } from '@fullerstack/ngx-logger';
import { UixService } from '@fullerstack/ngx-uix';
import { UserService } from '@fullerstack/ngx-user';
import { Observable } from 'rxjs';

@Component({
Expand All @@ -23,7 +24,8 @@ export class AppComponent implements OnInit {
readonly auth: AuthService,
readonly i18n: I18nService,
readonly uix: UixService,
readonly layout: LayoutService
readonly layout: LayoutService,
readonly user: UserService
) {
if (!this.config.options.production) {
/* istanbul ignore next */
Expand Down
13 changes: 9 additions & 4 deletions apps/fullerstack/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { HttpClientModule } from '@angular/common/http';
import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule } from '@angular/router';
import { AuthModule } from '@fullerstack/ngx-auth';
import { AuthInterceptor, AuthModule } from '@fullerstack/ngx-auth';
import { ConfigModule } from '@fullerstack/ngx-config';
import { GqlInterceptor } from '@fullerstack/ngx-gql';
import { GqlModule } from '@fullerstack/ngx-gql';
import { I18nModule } from '@fullerstack/ngx-i18n';
import { JwtModule } from '@fullerstack/ngx-jwt';
Expand All @@ -14,6 +15,7 @@ import { MaterialModule } from '@fullerstack/ngx-material';
import { MsgModule } from '@fullerstack/ngx-msg';
import { SharedModule } from '@fullerstack/ngx-shared';
import { UixModule } from '@fullerstack/ngx-uix';
import { UserModule } from '@fullerstack/ngx-user';
import { ValidationService } from '@fullerstack/ngx-util';
import { NgxsReduxDevtoolsPluginModule } from '@ngxs/devtools-plugin';
import { NgxsLoggerPluginModule } from '@ngxs/logger-plugin';
Expand All @@ -28,6 +30,7 @@ import { HomeComponent } from './pages/home/home.component';
import { LoginComponent } from './pages/login/login.component';
import { NotfoundComponent } from './pages/notfound/notfound.component';
import { RegisterComponent } from './pages/register/register.component';
import { ProfileUpdateComponent } from './pages/user/profile-update.component';

@NgModule({
declarations: [
Expand All @@ -37,6 +40,7 @@ import { RegisterComponent } from './pages/register/register.component';
RegisterComponent,
NotfoundComponent,
AppComponent,
ProfileUpdateComponent,
],
imports: [
BrowserModule,
Expand All @@ -58,13 +62,14 @@ import { RegisterComponent } from './pages/register/register.component';
GqlModule,
I18nModule.forRoot(),
AuthModule,
// UsrModule,
UserModule,
UixModule,
LayoutModule,
],
providers: [
ValidationService,
// { provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: AuthInterceptor, multi: true },
{ provide: HTTP_INTERCEPTORS, useClass: GqlInterceptor, multi: true },
],

bootstrap: [AppComponent],
Expand Down
11 changes: 11 additions & 0 deletions apps/fullerstack/src/app/app.routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { HomeComponent } from './pages/home/home.component';
import { LoginComponent } from './pages/login/login.component';
import { NotfoundComponent } from './pages/notfound/notfound.component';
import { RegisterComponent } from './pages/register/register.component';
import { ProfileUpdateComponent } from './pages/user/profile-update.component';

export const AppRoutes: Routes = [
{
Expand Down Expand Up @@ -37,6 +38,16 @@ export const AppRoutes: Routes = [
title: _('APP.REGISTER'),
},
},
{
path: 'user/profile/update',
component: ProfileUpdateComponent,
// canActivate: [GuardAuthenticationService],
// canDeactivate: [GuardDeactivateService],
data: {
title: _('COMMON.PROFILE_UPDATE'),
description: _('APP.DESCRIPTION.PROFILE_UPDATE'),
},
},
{
path: '**',
component: NotfoundComponent,
Expand Down
4 changes: 2 additions & 2 deletions apps/fullerstack/src/app/pages/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { tryGet } from '@fullerstack/agx-util';
import { AuthService } from '@fullerstack/ngx-auth';
import { ConfigService } from '@fullerstack/ngx-config';
import * as gqlSchema from '@fullerstack/ngx-gql/schema';
import { UserCredentialsInput } from '@fullerstack/ngx-gql/schema';
import { _ } from '@fullerstack/ngx-i18n';

@Component({
Expand All @@ -29,7 +29,7 @@ export class LoginComponent implements OnInit {
}
}

login(data: gqlSchema.UserCredentialsInput) {
login(data: UserCredentialsInput) {
this.auth.loginDispatch(data);
}
}
4 changes: 2 additions & 2 deletions apps/fullerstack/src/app/pages/register/register.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { tryGet } from '@fullerstack/agx-util';
import { AuthService } from '@fullerstack/ngx-auth';
import { ConfigService } from '@fullerstack/ngx-config';
import * as gqlSchema from '@fullerstack/ngx-gql/schema';
import { UserCreateInput } from '@fullerstack/ngx-gql/schema';
import { _ } from '@fullerstack/ngx-i18n';

@Component({
Expand All @@ -29,7 +29,7 @@ export class RegisterComponent implements OnInit {
}
}

register(data: gqlSchema.UserCreateInput) {
register(data: UserCreateInput) {
this.auth.registerDispatch(data);
}
}
32 changes: 32 additions & 0 deletions apps/fullerstack/src/app/pages/user/profile-update.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<mat-toolbar class="fs-page-header" color="primary"> </mat-toolbar>
<div class="fs-page-content">
<fullerstack-card
class="fs-page-card"
fxLayout="column"
fxFlex.xs="100"
fxFlex.sm="80"
fxFlex.gt-sm="600px"
[title]="title"
[subtitle]="subtitle"
[icon]="icon"
[progress]="user.isLoading"
>
<fullerstack-user-profile-form (submit$)="update($event)" [profile]="user.profile"></fullerstack-user-profile-form>

<mat-divider class="mt1"></mat-divider>

<div class="mt2" fxLayout="row">
<span>
[
<a routerLink="/auth/login" class="no-underline"> {{ 'COMMON.LOGIN' | translate }} </a>
]
</span>
<div fxFlex></div>
<span>
[
<a routerLink="/recovery/password/reset" class="no-underline"> {{ 'COMMON.FORGOT_PASSWORD' | translate }} </a>
]
</span>
</div>
</fullerstack-card>
</div>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { ProfileUpdateComponent } from './profile-update.component';

xdescribe('ProfileUpdateComponent', () => {
let component: ProfileUpdateComponent;
let fixture: ComponentFixture<ProfileUpdateComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ProfileUpdateComponent],
}).compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(ProfileUpdateComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
35 changes: 35 additions & 0 deletions apps/fullerstack/src/app/pages/user/profile-update.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Component, OnDestroy } from '@angular/core';
import { AuthService } from '@fullerstack/ngx-auth';
import { ConfigService } from '@fullerstack/ngx-config';
import { UserSelfUpdateInput } from '@fullerstack/ngx-gql/schema';
import { _ } from '@fullerstack/ngx-i18n';
import { UserService } from '@fullerstack/ngx-user';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';

@Component({
selector: 'fullerstack-user-profile-update',
templateUrl: './profile-update.component.html',
styleUrls: ['./profile-update.component.scss'],
})
export class ProfileUpdateComponent implements OnDestroy {
destroy$ = new Subject<boolean>();
title = _('COMMON.PROFILE');
subtitle = _('COMMON.PROFILE_UPDATE');
icon = 'account-edit-outline';

constructor(
readonly config: ConfigService,
readonly auth: AuthService,
readonly user: UserService
) {}

update(data: UserSelfUpdateInput) {
this.user.userSelfUpdate(data).pipe(takeUntil(this.destroy$)).subscribe();
}

ngOnDestroy() {
this.destroy$.next(true);
this.destroy$.complete();
}
}
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,6 @@ module.exports = {
'<rootDir>/libs/ngx-uix',
'<rootDir>/libs/ngx-util',
'<rootDir>/libs/ngx-shared',
'<rootDir>/libs/ngx-user',
],
};
29 changes: 11 additions & 18 deletions libs/ngx-auth/src/lib/auth.interceptor.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Injectable, Injector } from '@angular/core';
import { JWT_BEARER_REALM } from '@fullerstack/agx-dto';
import { Observable } from 'rxjs';
import { catchError, switchMap } from 'rxjs/operators';

import { AuthService } from './auth.service';
import { AuthEffectsService } from './store/auth-state.effect';

@Injectable()
@Injectable({ providedIn: 'root' })
export class AuthInterceptor implements HttpInterceptor {
constructor(readonly auth: AuthService, readonly effects: AuthEffectsService) {}
private auth: AuthService;

constructor(private injector: Injector) {
setTimeout(() => {
this.auth = this.injector.get(AuthService);
});
}

intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
if (this.auth.state.token) {
if (this.auth && this.auth.state.token) {
request = request.clone({
setHeaders: {
'Content-Type': 'application/json; charset=utf-8',
Expand All @@ -22,17 +26,6 @@ export class AuthInterceptor implements HttpInterceptor {
});
}

return next.handle(request).pipe(
catchError((error, caught$) => {
if (error.status === 401) {
return this.effects.tokenRefreshRequest().pipe(
switchMap(() => {
return next.handle(request);
})
);
}
return caught$;
})
);
return next.handle(request);
}
}
Loading

0 comments on commit 29d5956

Please sign in to comment.