fix: link generation should add prefix

This commit is contained in:
Carlos Valente
2025-03-18 21:47:51 +01:00
committed by Carlos Valente
parent b2eb140ee2
commit 0a6542df76
3 changed files with 66 additions and 6 deletions
@@ -0,0 +1,50 @@
import { generateAuthenticatedUrl } from '../session.service.js';
describe('generateAuthenticatedUrl()', () => {
describe('for local IP addresses', () => {
it('generates a link without locking or authentication', () => {
const localhostNotLocked = generateAuthenticatedUrl('http://localhost:3000', 'timer', false, false);
expect(localhostNotLocked.toString()).toBe('http://localhost:3000/timer');
});
it('generates a link with IP locking enabled', () => {
const ipLocked = generateAuthenticatedUrl('http://192.168.10.173:4001', 'timer', true, false);
expect(ipLocked.toString()).toBe('http://192.168.10.173:4001/timer?locked=true');
});
it('generates a link with authentication token and IP locking', () => {
const withAuth = generateAuthenticatedUrl('http://192.168.10.173:4001', 'timer', true, true, undefined, '1234');
expect(withAuth.toString()).toBe('http://192.168.10.173:4001/timer?token=1234&locked=true');
});
});
describe('for ontime-cloud URLs', () => {
it('generates a link without locking or authentication', () => {
const cloudNotLocked = generateAuthenticatedUrl(
'https://cloud.getontime.no/userhash',
'timer',
false,
false,
'prefix',
);
expect(cloudNotLocked.toString()).toBe('https://cloud.getontime.no/prefix/timer');
});
it('generates a link with IP locking enabled', () => {
const ipLocked = generateAuthenticatedUrl('https://cloud.getontime.no/prefix', 'timer', true, false, 'prefix');
expect(ipLocked.toString()).toBe('https://cloud.getontime.no/prefix/timer?locked=true');
});
it('generates a link with authentication token and IP locking', () => {
const withAuth = generateAuthenticatedUrl(
'https://cloud.getontime.no/prefix',
'timer',
true,
true,
'prefix',
'1234',
);
expect(withAuth.toString()).toBe('https://cloud.getontime.no/prefix/timer?token=1234&locked=true');
});
});
});
@@ -8,7 +8,7 @@ import { getLastLoadedProject } from '../../services/app-state-service/AppStateS
import { runtimeService } from '../../services/runtime-service/RuntimeService.js';
import { getNetworkInterfaces } from '../../utils/network.js';
import { getTimezoneLabel } from '../../utils/time.js';
import { password } from '../../externals.js';
import { password, routerPrefix } from '../../externals.js';
import { hashPassword } from '../../utils/hash.js';
const startedAt = new Date();
@@ -55,10 +55,19 @@ export const hashedPassword = hasPassword ? hashPassword(password as string) : u
/**
* Generates a pre-authenticated URL by injecting a token in the URL params
*/
export function generateAuthenticatedUrl(baseUrl: string, path: string, lock: boolean, authenticate: boolean): URL {
const url = new URL(path, baseUrl);
if (authenticate && hashedPassword) {
url.searchParams.append('token', hashedPassword);
export function generateAuthenticatedUrl(
baseUrl: string,
path: string,
lock: boolean,
authenticate: boolean,
prefix = routerPrefix,
hash = hashedPassword,
): URL {
const url = new URL(baseUrl);
url.pathname = prefix ? `${prefix}/${path}` : path;
if (authenticate && hash) {
url.searchParams.append('token', hash);
}
if (lock) {
url.searchParams.append('locked', 'true');
+2 -1
View File
@@ -16,13 +16,14 @@ export const isDocker = env === 'docker';
export const isProduction = isDocker || (env === 'production' && !isTest);
export const isOntimeCloud = Boolean(process.env.IS_CLOUD);
export const password = process.env.SESSION_PASSWORD;
export const routerPrefix = process.env.ROUTER_PREFIX;
/**
* Updates the router prefix in the index.html file
* This is only needed in the cloud environment where the client is not at the root segment
* ie: https://cloud.getontime.com/client-hash/timer
*/
export function updateRouterPrefix(prefix: string | undefined = process.env.ROUTER_PREFIX): string {
export function updateRouterPrefix(prefix: string | undefined = routerPrefix): string {
if (!prefix) {
return '';
}