Forráskód Böngészése

Refactoring of configuration and initialization

Lukas Angerer 3 éve
szülő
commit
496126b52a

+ 0 - 18
src/RunnersMeet.Client/authConfig.ts

@@ -1,18 +0,0 @@
-
-export interface AuthConfig {
-	domain: string;
-	clientId: string;
-	audience: string;
-	apiUri: string;
-	appUri: string;
-	errorPath: string;
-};
-
-export const authConfig: AuthConfig = {
-	domain: "dev-2ls6voifhbt37usw.eu.auth0.com",
-	clientId: "51IAWRARoNhevdmXODwxOb6xV2KEu1MO",
-	audience: "https://runners.larcanum.net",
-	apiUri: "https://localhost:7247",
-	appUri: "http://localhost:4200",
-	errorPath: "/error"
-};

+ 5 - 7
src/RunnersMeet.Client/src/app/app.module.ts

@@ -4,7 +4,6 @@ import { AuthHttpInterceptor, AuthModule } from '@auth0/auth0-angular';
 
 import { AppRoutingModule } from './app-routing.module';
 import { AppComponent } from './app.component';
-import { environment } from '../env/environment';
 import { HomePageComponent } from './pages/home-page/home-page.component';
 import { TracksPageComponent } from './pages/tracks-page/tracks-page.component';
 import { TracksApiService } from './tracks-api.service';
@@ -16,6 +15,8 @@ import { TrackListItemComponent } from './tracks/track-list-item/track-list-item
 import { TrackEditComponent } from './tracks/track-edit/track-edit.component';
 import { TrackViewComponent } from './tracks/track-view/track-view.component';
 import { ViewTrackPageComponent } from './pages/view-track-page/view-track-page.component';
+import { ConfigService } from './config.service';
+import { configInitializerProvider } from './initializer';
 
 @NgModule({
 	declarations: [
@@ -33,15 +34,12 @@ import { ViewTrackPageComponent } from './pages/view-track-page/view-track-page.
 		BrowserModule,
 		AppRoutingModule,
 		HttpClientModule,
-		AuthModule.forRoot({
-			...environment.auth0,
-			httpInterceptor: {
-				...environment.httpInterceptor,
-			},
-		}),
+		AuthModule.forRoot(),
 		FormsModule
 	],
 	providers: [
+		ConfigService,
+		configInitializerProvider,
 		{
 			provide: HTTP_INTERCEPTORS,
 			useClass: AuthHttpInterceptor,

+ 36 - 0
src/RunnersMeet.Client/src/app/config.service.ts

@@ -0,0 +1,36 @@
+import { Injectable } from "@angular/core";
+import { AuthConfig } from "@auth0/auth0-angular";
+
+@Injectable()
+export class ConfigService {
+	private config: AppConfig | null = null;
+
+	public get apiBaseUri(): string {
+		return this.config!.apiUri;
+	}
+
+	public initialize(config: AppConfig): void {
+		this.config = config;
+
+		// HTTP interceptor config can be derived from the rest of the config so we don't
+		// have to specify it explicitly in the app.config.json
+		this.config.auth.httpInterceptor = {
+			allowedList: [
+				`${this.config.apiUri}/*`
+			],
+		}
+	}
+
+	public auth0Config(): AuthConfig {
+		return this.config!.auth;
+	}
+
+	public apiUri(path: string): string {
+		return `${this.apiBaseUri}${path}`;
+	}
+}
+
+export interface AppConfig {
+	auth: AuthConfig;
+	apiUri: string;
+}

+ 26 - 0
src/RunnersMeet.Client/src/app/initializer.ts

@@ -0,0 +1,26 @@
+import { APP_INITIALIZER, Provider } from "@angular/core";
+import { AuthClientConfig } from "@auth0/auth0-angular";
+import { AppConfig, ConfigService } from "./config.service";
+
+/**
+ * See https://github.com/auth0/auth0-angular#dynamic-configuration
+ */
+export function configInitializer(
+	config: ConfigService,
+	authConfig: AuthClientConfig
+) {
+	return () =>
+		fetch('./assets/app.config.json')
+			.then(response => response.json())
+			.then((configData: AppConfig) => {
+				config.initialize(configData);
+				authConfig.set(config.auth0Config());
+			});
+}
+
+export const configInitializerProvider: Provider = {
+	provide: APP_INITIALIZER,
+	useFactory: configInitializer,
+	deps: [ConfigService, AuthClientConfig],
+	multi: true,
+};

+ 9 - 8
src/RunnersMeet.Client/src/app/tracks-api.service.ts

@@ -1,7 +1,7 @@
 import { HttpClient } from '@angular/common/http';
 import { Injectable } from '@angular/core';
 import { lastValueFrom } from 'rxjs';
-import { environment } from 'src/env/environment';
+import { ConfigService } from './config.service';
 import { Track } from './tracks/track';
 
 @Injectable({
@@ -10,35 +10,36 @@ import { Track } from './tracks/track';
 export class TracksApiService {
 
 	public constructor(
+		private readonly config: ConfigService,
 		private readonly http: HttpClient
 	) { }
 
 	public getTracks(): Promise<Track[]> {
-		return lastValueFrom(this.http.get<Track[]>(`${environment.apiUri}/api/tracks`));
+		return lastValueFrom(this.http.get<Track[]>(this.config.apiUri(`/api/tracks`)));
 	}
 
 	public createTrack(formData: FormData): Promise<Track> {
-		return lastValueFrom(this.http.post<Track>(`${environment.apiUri}/api/tracks`, formData));
+		return lastValueFrom(this.http.post<Track>(this.config.apiUri(`/api/tracks`), formData));
 	}
 
 	public getTrack(trackId: string): Promise<Track> {
-		return lastValueFrom(this.http.get<Track>(`${environment.apiUri}/api/tracks/${trackId}`));
+		return lastValueFrom(this.http.get<Track>(this.config.apiUri(`/api/tracks/${trackId}`)));
 	}
 
 	public updateTrack(track: Track): Promise<Track> {
-		return lastValueFrom(this.http.put<Track>(`${environment.apiUri}/api/tracks/${track.trackId}`, track));
+		return lastValueFrom(this.http.put<Track>(this.config.apiUri(`/api/tracks/${track.trackId}`), track));
 	}
 
 	public deleteTrack(track: Track): Promise<void> {
-		return lastValueFrom(this.http.delete(`${environment.apiUri}/api/tracks/${track.trackId}`)).then();
+		return lastValueFrom(this.http.delete(this.config.apiUri(`/api/tracks/${track.trackId}`))).then();
 	}
 
 	public getTrackGpxUrl(track: Track): string {
-		return `${environment.apiUri}/api/tracks/download/${track.fileHash}`;
+		return this.config.apiUri(`/api/tracks/download/${track.fileHash}`);
 	}
 
 	public downloadTrack(track: Track): Promise<{ blob: Blob | null, filename?: string }> {
-		return lastValueFrom(this.http.get(`${environment.apiUri}/api/tracks/download/${track.fileHash}`, {
+		return lastValueFrom(this.http.get(this.config.apiUri(`/api/tracks/download/${track.fileHash}`), {
 			responseType: 'blob',
 			observe: 'response'
 		})).then(response => {

+ 10 - 0
src/RunnersMeet.Client/src/assets/app.config.json

@@ -0,0 +1,10 @@
+{
+	"auth": {
+		"domain": "dev-2ls6voifhbt37usw.eu.auth0.com",
+		"clientId": "51IAWRARoNhevdmXODwxOb6xV2KEu1MO",
+		"audience": "https://runners.larcanum.net",
+		"appUri": "http://localhost:4200",
+		"errorPath": "/error"
+	},
+	"apiUri": "https://localhost:7247"
+}

+ 0 - 13
src/RunnersMeet.Client/src/env/environment.prod.ts

@@ -1,16 +1,3 @@
-import {authConfig} from '../../authConfig';
-
 export const environment = {
 	production: true,
-	apiUri: authConfig.apiUri,
-	auth0: {
-		domain: authConfig.domain,
-		clientId: authConfig.clientId,
-		audience: authConfig.audience,
-		redirectUri: window.location.origin,
-		errorPath: authConfig.errorPath,
-	},
-	httpInterceptor: {
-		allowedList: [`${authConfig.apiUri}/*`],
-	},
 };

+ 0 - 16
src/RunnersMeet.Client/src/env/environment.ts

@@ -2,22 +2,6 @@
 // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`.
 // The list of file replacements can be found in `angular.json`.
 
-import {authConfig} from '../../authConfig';
-
 export const environment = {
 	production: false,
-	apiUri: authConfig.apiUri,
-	auth0: {
-		domain: authConfig.domain,
-		clientId: authConfig.clientId,
-		audience: authConfig.audience,
-		redirectUri: window.location.origin,
-		errorPath: authConfig.errorPath,
-	},
-	httpInterceptor: {
-		// List of URI wildcard patterns for which the user's JWT will be added to requests
-		allowedList: [
-			`${authConfig.apiUri}/*`
-		],
-	},
 };