diff --git a/packages/tom-server/src/invitation-api/services/index.ts b/packages/tom-server/src/invitation-api/services/index.ts index 668833fb..e971c930 100644 --- a/packages/tom-server/src/invitation-api/services/index.ts +++ b/packages/tom-server/src/invitation-api/services/index.ts @@ -10,6 +10,7 @@ import { } from '../types' import { v7 as uuidv7 } from 'uuid' import { PATH } from '../routes' +import { buildUrl } from '../../utils' export default class InvitationService implements IInvitationService { private readonly EXPIRATION = 24 * 60 * 60 * 1000 // 24 hours @@ -110,7 +111,7 @@ export default class InvitationService implements IInvitationService { await this._storeMatrixInvite(payload, authorization, room_id) const token = await this._createInvitation(payload) - return `${this.config.base_url}${PATH}/${token}` + return buildUrl(this.config.base_url, `${PATH}/${token}`) } catch (error) { this.logger.error(`Failed to generate invitation link`, { error }) @@ -156,7 +157,7 @@ export default class InvitationService implements IInvitationService { ): Promise => { try { const response = await fetch( - `https://${this.config.matrix_server}${this.MATRIX_ROOM_PATH}`, + buildUrl(this.config.matrix_server, this.MATRIX_ROOM_PATH), { method: 'POST', headers: { @@ -251,22 +252,19 @@ export default class InvitationService implements IInvitationService { room_id: string ) => { try { - await fetch( - `https://${this.config.matrix_server}/${this.MATRIX_INVITE_PATH}`, - { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - Authorization: authorization - }, - body: JSON.stringify({ - medium: payload.medium, - address: payload.recepient, - sender: payload.sender, - room_id - }) - } - ) + await fetch(buildUrl(this.config.base_url, this.MATRIX_INVITE_PATH), { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: authorization + }, + body: JSON.stringify({ + medium: payload.medium, + address: payload.recepient, + sender: payload.sender, + room_id + }) + }) } catch (error) { this.logger.error(`Failed to store matrix invite`, { error }) diff --git a/packages/tom-server/src/invitation-api/tests/controller.test.ts b/packages/tom-server/src/invitation-api/tests/controller.test.ts index 35cdcadd..a7474094 100644 --- a/packages/tom-server/src/invitation-api/tests/controller.test.ts +++ b/packages/tom-server/src/invitation-api/tests/controller.test.ts @@ -53,7 +53,7 @@ app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: true })) app.use( router( - { matrix_server: 'http://localhost:789' } as unknown as Config, + { matrix_server: 'http://localhost:789', base_url: 'http://localhost' } as unknown as Config, dbMock as unknown as TwakeDB, authenticatorMock, loggerMock as unknown as TwakeLogger diff --git a/packages/tom-server/src/utils.ts b/packages/tom-server/src/utils.ts index 2c373a78..559b246b 100644 --- a/packages/tom-server/src/utils.ts +++ b/packages/tom-server/src/utils.ts @@ -10,3 +10,27 @@ export const tables = { invitations: 'id varchar(64) PRIMARY KEY, sender varchar(64), recepient varchar(64), medium varchar(64), expiration varchar(64), accessed int, room_id varchar(64)' } + +/** + * Builds a URL from a base URL and a path + * + * @param {string} base - Base URL + * @param {string} path - Path + * @returns {string} - URL + */ +export const buildUrl = (base: string, path: string): string => { + let formattedUrl = base + + if ( + !formattedUrl.startsWith('https://') && + !formattedUrl.startsWith('http://') + ) { + formattedUrl = `https://${formattedUrl}` + } + + const url = new URL(formattedUrl) + + url.pathname = path + + return url.toString() +}