Skip to content

Commit

Permalink
bring common cod on par with other branches
Browse files Browse the repository at this point in the history
Signed-off-by: Minecraftschurli <[email protected]>
  • Loading branch information
Georg Burkl authored and Minecraftschurli committed May 6, 2021
1 parent e24d993 commit 7095e9f
Show file tree
Hide file tree
Showing 27 changed files with 519 additions and 50 deletions.
2 changes: 1 addition & 1 deletion src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';


const routes: Routes = [];
const routes: Routes = [{ path: 'admin', loadChildren: () => import('./features/admin/admin.module').then(m => m.AdminModule) }];

@NgModule({
imports: [RouterModule.forRoot(routes)],
Expand Down
8 changes: 5 additions & 3 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Component } from '@angular/core';
import {Component, HostBinding} from '@angular/core';

@Component({
selector: 'app-root',
// eslint-disable-next-line @angular-eslint/component-selector
selector: 'body',
templateUrl: './app.component.html'
})
export class AppComponent {
title = 'Pfarre-Machstrasse';
@HostBinding('class') class = 'mat-typography';
title = 'Pfarre Machstrasse - Hl. Klaus von Flüe';
}
28 changes: 14 additions & 14 deletions src/app/auth/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class AuthService implements OnDestroy {

public login(username: string, password: string): Observable<boolean> {
if (!environment.production) {
this._user$.next({username, role: 'admin'});
this._user$.next({id: '', email: username, firstName: 'Demo', lastName: 'User', role: 'admin'});
return of(true);
}
return this._http
Expand Down Expand Up @@ -83,8 +83,8 @@ export class AuthService implements OnDestroy {
}

public setLocalStorage(x: LoginResult): void {
localStorage.setItem(ACCESS_TOKEN, x.access_token);
localStorage.setItem(REFRESH_TOKEN, x.refresh_token ?? null);
localStorage.setItem(ACCESS_TOKEN, x.accessToken);
localStorage.setItem(REFRESH_TOKEN, x.refreshToken ?? null);
localStorage.setItem('login-event', 'login' + Math.random());
}

Expand All @@ -94,17 +94,7 @@ export class AuthService implements OnDestroy {
localStorage.setItem('logout-event', 'logout' + Math.random());
}

private getTokenRemainingTime(): number {
const accessToken = this.getAccessToken();
if (!accessToken) {
return 0;
}
const jwtToken = JSON.parse(atob(accessToken.split('.')[1]));
const expires = new Date(jwtToken.exp * 1000);
return expires.getTime() - Date.now();
}

private refreshToken(): Observable<LoginResult> {
public refreshToken(): Observable<LoginResult> {
const refreshToken = this.getRefreshToken();
if (!refreshToken) {
this.doLogout();
Expand All @@ -123,6 +113,16 @@ export class AuthService implements OnDestroy {
);
}

private getTokenRemainingTime(): number {
const accessToken = this.getAccessToken();
if (!accessToken) {
return 0;
}
const jwtToken = JSON.parse(atob(accessToken.split('.')[1]));
const expires = new Date(jwtToken.exp * 1000);
return expires.getTime() - Date.now();
}

private updateUser(): void {
this._http.get<User>(this.userUrl).subscribe(user => this._user$.next(user));
}
Expand Down
6 changes: 5 additions & 1 deletion src/app/core/config/app-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ export interface IConfig {
apiEndpoint: string;
}

const NULL_CONFIG: IConfig = {
apiEndpoint: null
};

@Injectable()
export class AppConfig {
private static _config: IConfig;
public static get INSTANCE(): IConfig {
return AppConfig._config;
return AppConfig._config ?? NULL_CONFIG;
}
constructor(private _http: HttpClient) {}
load(): Promise<void> {
Expand Down
4 changes: 3 additions & 1 deletion src/app/core/core.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { CommonModule } from '@angular/common';
import { LoggingModule } from './logging/logging.module';
import {ErrorInterceptor} from './error.interceptor';
import {AppConfig} from './config/app-config';
import {JsonInterceptor} from './json.interceptor';


@NgModule({
Expand All @@ -16,7 +17,8 @@ import {AppConfig} from './config/app-config';
],
providers: [
AppConfig,
ErrorInterceptor
ErrorInterceptor,
JsonInterceptor
]
})
export class CoreModule {
Expand Down
4 changes: 4 additions & 0 deletions src/app/core/error.interceptor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export class ErrorInterceptor implements HttpInterceptor {
this._router.navigate(['']);
this._logger.error('Authentication error {0}', err?.message ?? err?.error?.message ?? err?.statusText);
}
if (err.status === 404) {
this._router.navigate(['']);
this._logger.error('Not found error {0}', err?.message ?? err?.error?.message ?? err?.statusText);
}
const error = err?.message ?? err?.error?.message ?? err?.statusText;
return throwError(error);
})
Expand Down
16 changes: 16 additions & 0 deletions src/app/core/json.interceptor.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { TestBed } from '@angular/core/testing';

import { JsonInterceptor } from './json.interceptor';

describe('JsonInterceptor', () => {
beforeEach(() => TestBed.configureTestingModule({
providers: [
JsonInterceptor
]
}));

it('should be created', () => {
const interceptor: JsonInterceptor = TestBed.inject(JsonInterceptor);
expect(interceptor).toBeTruthy();
});
});
57 changes: 57 additions & 0 deletions src/app/core/json.interceptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { Injectable } from '@angular/core';
import {
HttpRequest,
HttpHandler,
HttpEvent,
HttpInterceptor, HttpResponse
} from '@angular/common/http';
import { Observable } from 'rxjs';
import {map} from 'rxjs/operators';

const isArray = Array.isArray;

const isObject = (o) => o === Object(o) && !isArray(o) && typeof o !== 'function';

const toCamel = (s) => s.replace(/([-_][a-z])/ig, ($1) => $1.toUpperCase()
.replace('-', '')
.replace('_', ''));

const keysToCamel = (o) => {
if (isObject(o)) {
const n = {};

Object.keys(o)
.forEach((k) => {
n[toCamel(k)] = keysToCamel(o[k]);
});

return n;
} else if (isArray(o)) {
return o.map((i) => keysToCamel(i));
}

return o;
};

/**
* Intercept json responses and convert them to camelCase
*/
@Injectable()
export class JsonInterceptor implements HttpInterceptor {

intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
if (request.responseType === 'json') {
return next.handle(request).pipe(map(value => {
if (value instanceof HttpResponse) {
try {
return value.clone({body: keysToCamel(value.body)});
} catch (ignored) {
}
}
return value;
}));
} else {
return next.handle(request);
}
}
}
26 changes: 23 additions & 3 deletions src/app/data/category.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
import {Observable} from 'rxjs';
import {Page} from './page';

/**
* The DTO (DataTransferObject) for a category
*/
export interface CategoryDTO {
/**
* The id of this category
*/
id: string;
/**
* The title of this category
*/
title: string;
/**
* The ordering number of this category
*/
order: number;
}

export interface Category {
id: string;
title: string;
/**
* The full category object
*/
export interface Category extends CategoryDTO {
/**
* The direct accessor for all pages of this category<br>
* Executes a http request to fetch the pages
*
* @see Page
*/
pages$?: Observable<Page[]>;
}
32 changes: 32 additions & 0 deletions src/app/data/change.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export type ChangeType = 1 | 0 | -1;
export type ChangeData = ([ChangeType, string])[];

export interface Change {
/**
* The UUID of the User creating this change
*
* @type string uuid
*/
author: string;
/**
* The id of the category which the page of this change belongs to
*
* @see Category.id
* @see Page.category
*/
category: string;
/**
* The id of the page this change was made on
*
* @see Page.id
*/
page: string;
/**
* The timestamp of creation of this change
*/
createdAt: Date;
/**
* The data of this change
*/
data: ChangeData;
}
16 changes: 16 additions & 0 deletions src/app/data/event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {Observable} from 'rxjs';
import {Media} from './media';

export interface EventDTO {
id: string;
name: string;
details: string;
start: Date;
end: Date;
media: string | null;
owner: string;
}

export interface Event extends EventDTO {
media$: Observable<Media>;
}
8 changes: 8 additions & 0 deletions src/app/data/gallery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import {Media} from './media';

export interface Gallery {
id: string;
title: string;
owner: string;
media: Media[];
}
14 changes: 11 additions & 3 deletions src/app/data/login-result.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
/* eslint-disable @typescript-eslint/naming-convention */
/**
* The login result containing the JWT tokens for access and refresh
*/
export interface LoginResult {
access_token: string;
refresh_token?: string;
/**
* The JWT token used to authenticate with the backend
*/
accessToken: string;
/**
* The JWT token used to refresh the access token
*/
refreshToken?: string;
}
13 changes: 13 additions & 0 deletions src/app/data/media.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export interface MediaLinks {
file: string;
thumbnail: string;
}

export interface Media {
_links: MediaLinks;
id: string; //uuid
name: string;
mimetype: string;
extension: string;
owner: string; //uuid
}
27 changes: 24 additions & 3 deletions src/app/data/page.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,33 @@
import {Observable} from 'rxjs';

/**
* The DTO (DataTransferObject) for a page
*/
export interface PageDTO {
/**
* The id of this page
*/
id: string;
/**
* The title of this page
*/
title: string;
/**
* The category this page belongs to
*/
category: string;
/**
* The position of the page insede the category
*/
order: number;
}

export interface Page {
id: string;
title: string;
/**
* The full page object
*/
export interface Page extends PageDTO {
/**
* The direct accessor for the content of this page
*/
content$: Observable<string>;
}
5 changes: 5 additions & 0 deletions src/app/data/upload-result.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface UploadResult {
name: string;
url: string;
media: boolean;
}
24 changes: 23 additions & 1 deletion src/app/data/user.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
export type Role = 'admin' | 'author';

/**
* The object representing a user
*/
export interface User {
username: string;
/**
* The UUID of the user
*/
id: string;
/**
* The users email
*/
email: string;
/**
* The users first name
*/
firstName: string;
/**
* The users last name
*/
lastName: string;
/**
* The users role
*/
role: Role;
}
Loading

0 comments on commit 7095e9f

Please sign in to comment.