Skip to content

Commit e471f2e

Browse files
LucHeartCopilot
andauthored
Feature/use full urls in env config (#143)
* Use full urls in env config * fix configs * Update svelte.config.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update svelte.config.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update src/lib/api/index.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix path getting replaced * fix returning url on oauth string * Update src/lib/api/index.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 6d6e5b4 commit e471f2e

10 files changed

Lines changed: 78 additions & 49 deletions

File tree

.env.development

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
PUBLIC_SITE_DOMAIN=openshock.dev
2-
PUBLIC_SITE_SHORT_DOMAIN=openshock.dev
3-
PUBLIC_BACKEND_API_DOMAIN=api.openshock.dev
4-
PUBLIC_GATEWAY_CSP_WILDCARD=*.openshock.dev
1+
PUBLIC_SITE_URL=https://openshock.dev
2+
PUBLIC_SITE_SHORT_URL=https://openshock.dev
3+
PUBLIC_BACKEND_API_URL=https://api.openshock.dev
4+
PUBLIC_GATEWAY_CSP_WILDCARD=https://*.openshock.dev
55

66
PUBLIC_TURNSTILE_DEV_BYPASS_VALUE=dev-bypass
77
PUBLIC_DEVELOPMENT_BANNER=true

.env.production

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
PUBLIC_SITE_DOMAIN=openshock.app
2-
PUBLIC_SITE_SHORT_DOMAIN=openshock.app
3-
PUBLIC_BACKEND_API_DOMAIN=api.openshock.app
4-
PUBLIC_GATEWAY_CSP_WILDCARD=*.openshock.app
1+
PUBLIC_SITE_URL=https://openshock.app
2+
PUBLIC_SITE_SHORT_URL=https://openshock.app
3+
PUBLIC_BACKEND_API_URL=https://api.openshock.app
4+
PUBLIC_GATEWAY_CSP_WILDCARD=https://*.openshock.app

.env.test

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
PUBLIC_SITE_DOMAIN=openshock.dev
2-
PUBLIC_SITE_SHORT_DOMAIN=openshock.dev
3-
PUBLIC_BACKEND_API_DOMAIN=api.openshock.dev
4-
PUBLIC_GATEWAY_CSP_WILDCARD=*.openshock.dev
1+
PUBLIC_SITE_URL=https://openshock.dev
2+
PUBLIC_SITE_SHORT_URL=https://openshock.dev
3+
PUBLIC_BACKEND_API_URL=https://api.openshock.dev
4+
PUBLIC_GATEWAY_CSP_WILDCARD=https://*.openshock.dev
55

66
PUBLIC_TURNSTILE_DEV_BYPASS_VALUE=dev-bypass

src/lib/api/index.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { PUBLIC_BACKEND_API_DOMAIN } from '$env/static/public';
1+
import { PUBLIC_BACKEND_API_URL } from '$env/static/public';
2+
23
import {
34
APITokensApi,
45
AccountApi as AccountV1Api,
@@ -22,17 +23,21 @@ import {
2223
} from './internal/v2';
2324

2425
function GetBasePath() {
25-
const domain = (PUBLIC_BACKEND_API_DOMAIN || undefined) as string | undefined;
26-
27-
if (!domain) {
28-
return undefined;
26+
if (!PUBLIC_BACKEND_API_URL) {
27+
throw new Error('PUBLIC_BACKEND_API_URL is not set in the environment');
2928
}
3029

31-
if (!/^[a-z0-9.-]+$/i.test(domain)) {
32-
return undefined;
30+
try {
31+
const parsedUrl = new URL(PUBLIC_BACKEND_API_URL);
32+
// Remove trailing slash unless the path is just "/"
33+
let basePath = parsedUrl.toString();
34+
if (basePath.endsWith('/') && basePath.length > parsedUrl.origin.length + 1) {
35+
basePath = basePath.slice(0, -1);
36+
}
37+
return basePath;
38+
} catch (error: any) {
39+
throw new Error('PUBLIC_BACKEND_API_URL is not a valid URL', { cause: error });
3340
}
34-
35-
return 'https://' + domain; // TODO: Add configurable protocol
3641
}
3742

3843
function GetConfig(): ConfigurationParameters {

src/lib/api/next/base.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,15 @@
1-
import { PUBLIC_BACKEND_API_DOMAIN } from '$env/static/public';
1+
import { PUBLIC_BACKEND_API_URL } from '$env/static/public';
22
import { ResponseError } from './ResponseError';
33

4-
const BaseUrl = `https://${PUBLIC_BACKEND_API_DOMAIN}`;
5-
64
type ApiVersion = 1 | 2;
7-
export type Path = `/${ApiVersion}/${string}`;
8-
9-
export function GetBackendUrl(path: Path) {
10-
return BaseUrl + path;
11-
}
5+
export type Path = `${ApiVersion}/${string}`;
126

137
export async function GetJson<T>(
148
path: Path,
159
expectedStatus = 200,
1610
transformer: (data: unknown) => T
1711
): Promise<T> {
18-
const res = await fetch(BaseUrl + path, {
12+
const res = await fetch(GetBackendUrl(path), {
1913
method: 'GET',
2014
headers: { accept: 'application/json' },
2115
credentials: 'include',
@@ -36,6 +30,11 @@ export async function GetJson<T>(
3630
return transformer(data);
3731
}
3832

33+
export function GetBackendUrl(path: Path): URL {
34+
const url = new URL(path, PUBLIC_BACKEND_API_URL);
35+
return url;
36+
}
37+
3938
export async function PostJson<T>(
4039
path: Path,
4140
body: unknown,

src/lib/api/next/oauth.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@ import { GetBackendUrl, GetJson, PostJson } from './base';
22
import type { LoginOkResponse, OAuthFinalizeRequest, OAuthSignupData } from './models';
33
import { TransformLoginOkResponse, TransformOAuthSignupData } from './transformers';
44

5-
export function GetOAuthAuthorizeUrl(provider: string, flow: 'LoginOrCreate' | 'Link') {
5+
export function GetOAuthAuthorizeUrl(provider: string, flow: 'LoginOrCreate' | 'Link'): string {
66
const providerEnc = encodeURIComponent(provider);
77
const flowEnc = encodeURIComponent(flow);
8-
return GetBackendUrl(`/1/oauth/${providerEnc}/authorize?flow=${flowEnc}`);
8+
return GetBackendUrl(`1/oauth/${providerEnc}/authorize?flow=${flowEnc}`).toString();
99
}
1010

1111
export async function OAuthSignupGetData(provider: string) {
1212
const providerEnc = encodeURIComponent(provider);
1313
return GetJson<OAuthSignupData>(
14-
`/1/oauth/${providerEnc}/signup-data`,
14+
`1/oauth/${providerEnc}/signup-data`,
1515
200,
1616
TransformOAuthSignupData
1717
);
@@ -23,7 +23,7 @@ export async function OAuthSignupFinalize(
2323
): Promise<LoginOkResponse> {
2424
const providerEnc = encodeURIComponent(provider);
2525
return PostJson(
26-
`/1/oauth/${providerEnc}/signup-finalize`,
26+
`1/oauth/${providerEnc}/signup-finalize`,
2727
payload,
2828
200,
2929
TransformLoginOkResponse

src/lib/signalr/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
LogLevel,
77
} from '@microsoft/signalr';
88
import { dev } from '$app/environment';
9-
import { PUBLIC_BACKEND_API_DOMAIN } from '$env/static/public';
9+
import { PUBLIC_BACKEND_API_URL } from '$env/static/public';
1010
import { toast } from 'svelte-sonner';
1111
import { type Readable, get, writable } from 'svelte/store';
1212
import {
@@ -31,7 +31,7 @@ export async function initializeSignalR() {
3131

3232
connection = new HubConnectionBuilder()
3333
.configureLogging(dev ? LogLevel.Debug : LogLevel.Warning)
34-
.withUrl(`https://${PUBLIC_BACKEND_API_DOMAIN}/1/hubs/user`, {
34+
.withUrl(new URL(`1/hubs/user`, PUBLIC_BACKEND_API_URL).toString(), {
3535
transport: HttpTransportType.WebSockets,
3636
skipNegotiation: true,
3737
})

src/routes/(anonymous)/+page.server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { PUBLIC_BACKEND_API_DOMAIN } from '$env/static/public';
1+
import { PUBLIC_BACKEND_API_URL } from '$env/static/public';
22
import { Configuration, MetaApi } from '$lib/api/internal/v1';
33

44
type ResponseType = Promise<{ ok: false; error: string } | { ok: true; deviceCount: number }>;
@@ -16,7 +16,7 @@ export async function load({ setHeaders }): ResponseType {
1616
try {
1717
const metaApi = new MetaApi(
1818
new Configuration({
19-
basePath: 'https://' + PUBLIC_BACKEND_API_DOMAIN,
19+
basePath: PUBLIC_BACKEND_API_URL,
2020
headers: {
2121
'User-Agent': 'OpenShockFrontend/1.0 (ServerSide)',
2222
},

svelte.config.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,28 @@ function getGitBranch() {
3131
return child_process.execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
3232
}
3333

34+
function getWsUrlFromHttpUrl(url) {
35+
if (url.startsWith('https://')) {
36+
return url.replace('https://', 'wss://');
37+
} else if (url.startsWith('http://')) {
38+
return url.replace('http://', 'ws://');
39+
}
40+
41+
throw new Error(`Invalid URL was provided, it must start with http:// or https:// [${url}]`);
42+
}
43+
44+
function getSvelteBasePath() {
45+
try {
46+
const url = new URL(dotenv.PUBLIC_SITE_URL);
47+
const path = url.pathname === '/' ? '' : url.pathname;
48+
console.log(`Using base path: [${path}] from PUBLIC_SITE_URL: ${dotenv.PUBLIC_SITE_URL}`);
49+
return path;
50+
} catch (error) {
51+
throw new Error(`PUBLIC_SITE_URL is not a valid URL: ${error.message}`, { cause: error });
52+
}
53+
54+
}
55+
3456
const commitHash = getGitHash();
3557
const branchName = getGitBranch();
3658

@@ -49,6 +71,9 @@ const config = {
4971
},
5072
kit: {
5173
adapter: adapter(),
74+
paths: {
75+
base: getSvelteBasePath()
76+
},
5277
csp: {
5378
mode: 'hash',
5479
directives: {
@@ -65,9 +90,10 @@ const config = {
6590
],
6691
'connect-src': [
6792
'self',
68-
'https://' + dotenv.PUBLIC_BACKEND_API_DOMAIN,
69-
'wss://' + dotenv.PUBLIC_BACKEND_API_DOMAIN,
70-
'wss://' + dotenv.PUBLIC_GATEWAY_CSP_WILDCARD,
93+
dotenv.PUBLIC_BACKEND_API_URL,
94+
getWsUrlFromHttpUrl(dotenv.PUBLIC_BACKEND_API_URL),
95+
dotenv.PUBLIC_GATEWAY_CSP_WILDCARD,
96+
getWsUrlFromHttpUrl(dotenv.PUBLIC_GATEWAY_CSP_WILDCARD),
7197
'https://firmware.openshock.org',
7298
'https://api.pwnedpasswords.com/range/',
7399
'https://cloudflareinsights.com',

vite.config.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -66,17 +66,16 @@ function getPlugins(useLocalRedirect: boolean): PluginOption[] {
6666
}
6767

6868
async function getServerConfig(mode: string, useLocalRedirect: boolean) {
69-
if (!useLocalRedirect) return undefined;
70-
7169
const vars = { ...env, ...loadEnv(mode, process.cwd(), ['PUBLIC_']) };
72-
const domain = vars.PUBLIC_SITE_DOMAIN;
73-
74-
// Load environment variables
75-
if (!domain) {
76-
printError('PUBLIC_SITE_DOMAIN must be set in your environment');
70+
if(!vars.PUBLIC_SITE_URL) {
71+
printError('PUBLIC_SITE_URL must be set in your environment');
7772
process.exit(1);
7873
}
7974

75+
if (!useLocalRedirect) return undefined;
76+
77+
const domain = new URL(vars.PUBLIC_SITE_URL).hostname;
78+
8079
if (domain === 'localhost') {
8180
return { host: 'localhost', port: 8080, proxy: {} };
8281
}
@@ -93,7 +92,7 @@ export default defineConfig(async ({ command, mode, isPreview }) => {
9392
const isLocalServe = command === 'serve' || isPreview === true;
9493
const isProduction = mode === 'production' && (isTruthy(env.DOCKER) || isTruthy(env.CF_PAGES));
9594

96-
// If we are running locally, ensure that local.{PUBLIC_SITE_DOMAIN} resolves to localhost, and then use mkcert to generate a certificate
95+
// If we are running locally, ensure that local.{PUBLIC_SITE_URL} resolves to localhost, and then use mkcert to generate a certificate
9796
const useLocalRedirect = isLocalServe && !isProduction && !isTruthy(env.CI);
9897

9998
return defineConfig({

0 commit comments

Comments
 (0)