Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relative DB URLs #1319

Merged
merged 41 commits into from
Jul 28, 2022
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
4b537b6
removed usage of remote_url
TheSlimvReal Jun 23, 2022
3a12b4c
removed database name from config
TheSlimvReal Jun 23, 2022
39dd063
added comments for proxy url
TheSlimvReal Jun 24, 2022
031ee25
removed usages of remote_url for database
TheSlimvReal Jun 24, 2022
3e8e55a
fixed lint error
TheSlimvReal Jun 24, 2022
b36e871
Merge remote-tracking branch 'origin/master' into relative-url
TheSlimvReal Jul 6, 2022
6b5b981
removed remote_url from default config
TheSlimvReal Jul 6, 2022
93974ce
removed database name and replaced it by a static value
TheSlimvReal Jul 6, 2022
faeca34
removed site_name from config.json and moved it to db config
TheSlimvReal Jul 6, 2022
b4f7b06
fixed tests
TheSlimvReal Jul 6, 2022
6f25216
removed session type from config.json and moved it environment or que…
TheSlimvReal Jul 6, 2022
70d87d4
added default env options to prod settings
TheSlimvReal Jul 7, 2022
edcfba0
added demo redirect to nginx conf and option to disable it to dockerfile
TheSlimvReal Jul 8, 2022
b502680
cleaned up initialization of AppConfig settings and removed old refer…
TheSlimvReal Jul 8, 2022
e7f2ff8
fixed tests
TheSlimvReal Jul 8, 2022
150963f
Merge branch 'master' into relative-url
TheSlimvReal Jul 8, 2022
aee3697
fix doc styling
TheSlimvReal Jul 8, 2022
6503623
Merge remote-tracking branch 'origin/relative-url' into relative-url
TheSlimvReal Jul 8, 2022
39091ab
disabled port in redirect
TheSlimvReal Jul 8, 2022
f8d81d1
fixed typo
TheSlimvReal Jul 8, 2022
eb0cca5
better rewriting to use correct port and schema
TheSlimvReal Jul 8, 2022
e8d9b1d
using https on default
TheSlimvReal Jul 8, 2022
688cddb
changed try-files clause for language locations
TheSlimvReal Jul 11, 2022
862eb3c
directly navigating to index.html file on language change
TheSlimvReal Jul 11, 2022
1f34781
Merge remote-tracking branch 'origin/master' into relative-url
TheSlimvReal Jul 19, 2022
35a62c1
added automatic demo query params to new nginx config
TheSlimvReal Jul 19, 2022
0ea0c8c
Merge remote-tracking branch 'origin/relative-url' into relative-url
TheSlimvReal Jul 19, 2022
281f97d
files are captured in separate location block
TheSlimvReal Jul 19, 2022
62a6673
enforcing https in rewrite
TheSlimvReal Jul 19, 2022
579dc82
using correct host variable
TheSlimvReal Jul 19, 2022
da65aee
added local storage option to preserve query params
TheSlimvReal Jul 19, 2022
90a0273
using permanent rewrite for demo mode
TheSlimvReal Jul 19, 2022
9b407e1
improved documentation
TheSlimvReal Jul 19, 2022
db88268
added comment about heroku workaround
TheSlimvReal Jul 19, 2022
1ff29ab
removed webdav references
TheSlimvReal Jul 27, 2022
2ef6fd8
cleaned up demo check in nginx config
TheSlimvReal Jul 27, 2022
13985d3
cleaned up fetching of runtime settings
TheSlimvReal Jul 27, 2022
1532db3
renamed AppConfig to AppSettings
TheSlimvReal Jul 27, 2022
18de486
changed order of config attributes
TheSlimvReal Jul 27, 2022
fb3df4b
removed config.default.json
TheSlimvReal Jul 27, 2022
474572e
moved demo_mode and session_type to environment.ts
TheSlimvReal Jul 27, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions build/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# This docker image can be used to run the application locally.
# To use it only Docker needs to be installed locally
# Run the following commands from the root folder to build, run and kill the application
# >> docker build -f build/Dockerfile -t aam/digital:latest .
# >> docker run -p=80:80 aam/digital:latest
# >> docker kill aam-digital
# >> docker build -f build/Dockerfile -t aam-digital .
# >> docker run -p=80:80 aam-digital
FROM node:16.14.2-alpine3.15 as builder
WORKDIR /app

Expand Down Expand Up @@ -71,6 +70,8 @@ ENV PORT=80
ENV WEBDAV_URL="http://localhost"
# The url to the CouchDB database
ENV COUCHDB_URL="http://localhost"
# Whether the app should be started in demo mode. Everything else then "true" is considered as "false".
ENV DEMO="true"
# variables are inserted into the nginx config
CMD envsubst '$$PORT $$WEBDAV_URL $$COUCHDB_URL' < /etc/nginx/templates/default.conf > /etc/nginx/conf.d/default.conf &&\
CMD envsubst '$$PORT $$WEBDAV_URL $$COUCHDB_URL $$DEMO' < /etc/nginx/templates/default.conf > /etc/nginx/conf.d/default.conf &&\
TheSlimvReal marked this conversation as resolved.
Show resolved Hide resolved
nginx -g 'daemon off;'
16 changes: 16 additions & 0 deletions build/default.conf
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,22 @@ server {
try_files $uri =404;
}

# Files should be directly accessed
location ~* \.[a-zA-Z]+$ {
try_files $uri =404;
}

location / {
# Demo mode params are added to URL when not yet present and DEMO is set to true
if ($arg_demo != "true") {
set $demo "${DEMO}true";
TheSlimvReal marked this conversation as resolved.
Show resolved Hide resolved
}
if ($demo = "truetrue") {
# This first part is required because Heroku does some internal redirects which break the rewrite otherwise
# This does not work in localhost as it enforces HTTPS
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have to rewrite to https here or could we just leave it at whatever was used before?

It would make more sense to have a separate block that rewrites any mode to use https (easier to understand if separated - and applying to all modes). But I don't know whether that's doable in nginx, e.g. multiple rewrite blocks applying.

Copy link
Collaborator Author

@TheSlimvReal TheSlimvReal Jul 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally it definitely works the way you are asking for the problem is that it does not work with Heroku. Somehow in there a internal redirect is happening before this one which leads to a wrong URL in this rewrite (in particular loosing the https and adding a wrong port). This workaround is not needed for our own servers. There we could just use:

rewrite ^ $uri?demo=true&session=mock permanent;

rewrite ^ https://$http_host$uri?demo=true&session=mock permanent;
}

index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
Expand All @@ -27,6 +42,7 @@ server {
root /usr/share/nginx/html;
}

# The proxy path should be the same as in AppConfig.DB_PROXY_PREFIX
location ^~ /db {
rewrite /db/(.*) /$1 break;
proxy_pass ${COUCHDB_URL};
Expand Down
39 changes: 14 additions & 25 deletions src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,11 @@ import {
fakeAsync,
flush,
TestBed,
tick,
waitForAsync,
} from "@angular/core/testing";
import { AppComponent } from "./app.component";
import { AppModule } from "./app.module";
import { AppConfig } from "./core/app-config/app-config";
import { IAppConfig } from "./core/app-config/app-config.model";
import { Config } from "./core/config/config";
import { USAGE_ANALYTICS_CONFIG_ID } from "./core/analytics/usage-analytics-config";
import { environment } from "../environments/environment";
Expand All @@ -47,28 +45,19 @@ describe("AppComponent", () => {
let fixture: ComponentFixture<AppComponent>;
let entityUpdates: Subject<UpdatedEntity<Config>>;

const mockAppSettings: IAppConfig = {
database: { name: "", remote_url: "" },
session_type: SessionType.local,
demo_mode: false,
site_name: "",
};
beforeEach(waitForAsync(() => {
AppConfig.SESSION_TYPE = SessionType.mock;
const entityMapper = mockEntityMapper();
entityUpdates = new Subject();
spyOn(entityMapper, "receiveUpdates").and.returnValue(entityUpdates);

beforeEach(
waitForAsync(() => {
AppConfig.settings = mockAppSettings;
const entityMapper = mockEntityMapper();
entityUpdates = new Subject();
spyOn(entityMapper, "receiveUpdates").and.returnValue(entityUpdates);
TestBed.configureTestingModule({
imports: [AppModule, HttpClientTestingModule],
providers: [{ provide: EntityMapperService, useValue: entityMapper }],
}).compileComponents();

TestBed.configureTestingModule({
imports: [AppModule, HttpClientTestingModule],
providers: [{ provide: EntityMapperService, useValue: entityMapper }],
}).compileComponents();

spyOn(TestBed.inject(EntityRegistry), "add"); // Prevent error with duplicate registration
})
);
spyOn(TestBed.inject(EntityRegistry), "add"); // Prevent error with duplicate registration
}));

function createComponent() {
fixture = TestBed.createComponent(AppComponent);
Expand Down Expand Up @@ -101,7 +90,7 @@ describe("AppComponent", () => {
window["_paq"] = [];

createComponent();
tick();
flush();

expect(startTrackingSpy).toHaveBeenCalledTimes(1);
expect(window["_paq"]).toContain([
Expand All @@ -115,13 +104,13 @@ describe("AppComponent", () => {
it("published the demo data", fakeAsync(() => {
const demoDataService = TestBed.inject(DemoDataService);
spyOn(demoDataService, "publishDemoData").and.callThrough();
AppConfig.settings.demo_mode = true;
AppConfig.DEMO_MODE = true;

createComponent();
flush();
discardPeriodicTasks();

expect(demoDataService.publishDemoData).toHaveBeenCalled();
AppConfig.settings.demo_mode = false;
AppConfig.DEMO_MODE = false;
}));
});
2 changes: 1 addition & 1 deletion src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ export class AppComponent {
this.analyticsService.init();
}

if (AppConfig.settings.demo_mode) {
if (AppConfig.DEMO_MODE) {
await this.demoDataInitializer.run();
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ import {
DEFAULT_LANGUAGE,
LANGUAGE_LOCAL_STORAGE_KEY,
} from "./core/language/language-statics";
import { AppConfig } from "./core/app-config/app-config";

/**
* Main entry point of the application.
Expand Down Expand Up @@ -177,6 +178,7 @@ import {
})
export class AppModule {
constructor(icons: FaIconLibrary) {
AppConfig.initSettings();
icons.addIconPacks(fas, far);
}
}
Expand Down
29 changes: 12 additions & 17 deletions src/app/core/admin/admin/admin.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ <h1>Administration & Configuration</h1>
you know what you are doing.
</p>

<br />
<hr />
<br/>
<hr/>
<h2>Utility Functions</h2>
<p fxLayoutGap="12px">
<button
Expand All @@ -17,8 +17,8 @@ <h2>Utility Functions</h2>
</button>
</p>

<br />
<hr />
<br/>
<hr/>
<h2>Backup</h2>
<p>
<button
Expand All @@ -42,8 +42,8 @@ <h2>Backup</h2>
/>
</p>

<br />
<hr />
<br/>
<hr/>
<h2>Export</h2>
<p>
<button
Expand All @@ -54,8 +54,8 @@ <h2>Export</h2>
</button>
&nbsp;
</p>
<br />
<hr />
<br/>
<hr/>
<h2>Application Configuration</h2>
<p>
<button
Expand All @@ -79,13 +79,8 @@ <h2>Application Configuration</h2>
/>
</p>

<br />
<hr />
<h2>AppConfig</h2>
<p>{{ appConfig | json }}</p>

<br />
<hr />
<br/>
<hr/>
<h2>Debug the PouchDB</h2>
<p>
<button (click)="debugDatabase()" mat-stroked-button>
Expand All @@ -101,8 +96,8 @@ <h2>Debug the PouchDB</h2>
</button>
</p>

<br />
<hr />
<br/>
<hr/>
<h2>Alert Log</h2>
<table aria-label="Table showing alerts">
<tr *ngFor="let alert of alerts.reverse()">
Expand Down
9 changes: 1 addition & 8 deletions src/app/core/admin/admin/admin.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,7 @@ describe("AdminComponent", () => {

beforeEach(
waitForAsync(() => {
AppConfig.settings = {
site_name: "",
session_type: SessionType.mock,
database: {
name: "unit-tests",
remote_url: "",
},
};
AppConfig.SESSION_TYPE = SessionType.mock;

TestBed.configureTestingModule({
imports: [AdminModule, MockedTestingModule.withState()],
Expand Down
4 changes: 0 additions & 4 deletions src/app/core/admin/admin/admin.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Component, OnInit } from "@angular/core";
import { AppConfig } from "../../app-config/app-config";
import { AlertService } from "../../alerts/alert.service";
import { Alert } from "../../alerts/alert";
import { BackupService } from "../services/backup.service";
Expand All @@ -23,9 +22,6 @@ import { Database } from "../../database/database";
styleUrls: ["./admin.component.scss"],
})
export class AdminComponent implements OnInit {
/** app-wide configuration */
appConfig = AppConfig.settings;

/** all alerts */
alerts: Alert[];

Expand Down
3 changes: 0 additions & 3 deletions src/app/core/analytics/analytics.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import { Angulartics2Matomo, Angulartics2Module } from "angulartics2";
import { RouterTestingModule } from "@angular/router/testing";
import { ConfigService } from "../config/config.service";
import { UsageAnalyticsConfig } from "./usage-analytics-config";
import { AppConfig } from "../app-config/app-config";
import { IAppConfig } from "../app-config/app-config.model";
import { Subject } from "rxjs";
import { Config } from "../config/config";

Expand All @@ -18,7 +16,6 @@ describe("AnalyticsService", () => {
let mockMatomo: jasmine.SpyObj<Angulartics2Matomo>;

beforeEach(() => {
AppConfig.settings = { site_name: "unit-testing" } as IAppConfig;
mockConfigService = jasmine.createSpyObj(
"mockConfigService",
["getConfig"],
Expand Down
22 changes: 13 additions & 9 deletions src/app/core/analytics/analytics.service.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { Injectable } from "@angular/core";
import { environment } from "../../../environments/environment";
import { AppConfig } from "../app-config/app-config";
import { ConfigService } from "../config/config.service";
import {
USAGE_ANALYTICS_CONFIG_ID,
UsageAnalyticsConfig,
} from "./usage-analytics-config";
import { Angulartics2, Angulartics2Matomo } from "angulartics2";
import md5 from "md5";
import { UiConfig } from "../ui/ui-config";

/**
* Track usage analytics data and report it to a backend server like Matomo.
Expand All @@ -18,10 +18,6 @@ import md5 from "md5";
providedIn: "root",
})
export class AnalyticsService {
private static getUserHash(username: string): string {
return md5(AppConfig.settings?.site_name + username);
}

private isInitialized = false;

constructor(
Expand All @@ -30,10 +26,14 @@ export class AnalyticsService {
private configService: ConfigService
) {}

/**
* Sets a unique user hash which is always for the same user but does not expose the username.
* This improves the logging behavior.
* @param username actual username
*/
public setUser(username: string): void {
this.angulartics2Matomo.setUsername(
AnalyticsService.getUserHash(username ?? "")
);
const baseUrl = location.host;
this.angulartics2Matomo.setUsername(md5(`${baseUrl}${username ?? ""}`));
}

/**
Expand All @@ -48,7 +48,6 @@ export class AnalyticsService {
window["_paq"].push(["trackPageView"]);
window["_paq"].push(["enableLinkTracking"]);
this.setVersion();
this.setOrganization(AppConfig.settings.site_name);
this.setUser(undefined);
this.configService.configUpdates.subscribe(() => this.setConfigValues());
}
Expand Down Expand Up @@ -101,6 +100,11 @@ export class AnalyticsService {
if (site_id) {
window["_paq"].push(["setSiteId", site_id]);
}
const { site_name } =
this.configService.getConfig<UiConfig>("appConfig") || {};
if (site_name) {
this.setOrganization(site_name);
}
}

/**
Expand Down
Loading