Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
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
8 changes: 4 additions & 4 deletions .env.development
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PUBLIC_SITE_DOMAIN=openshock.dev
PUBLIC_SITE_SHORT_DOMAIN=openshock.dev
PUBLIC_BACKEND_API_DOMAIN=api.openshock.dev
PUBLIC_GATEWAY_CSP_WILDCARD=*.openshock.dev
PUBLIC_SITE_URL=https://openshock.dev
PUBLIC_SITE_SHORT_URL=https://openshock.dev
PUBLIC_BACKEND_API_URL=https://api.openshock.dev
PUBLIC_GATEWAY_CSP_WILDCARD=https://*.openshock.dev

PUBLIC_TURNSTILE_DEV_BYPASS_VALUE=dev-bypass
PUBLIC_DEVELOPMENT_BANNER=true
8 changes: 4 additions & 4 deletions .env.production
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PUBLIC_SITE_DOMAIN=openshock.app
PUBLIC_SITE_SHORT_DOMAIN=openshock.app
PUBLIC_BACKEND_API_DOMAIN=api.openshock.app
PUBLIC_GATEWAY_CSP_WILDCARD=*.openshock.app
PUBLIC_SITE_URL=https://openshock.app
PUBLIC_SITE_SHORT_URL=https://openshock.app
PUBLIC_BACKEND_API_URL=https://api.openshock.app
PUBLIC_GATEWAY_CSP_WILDCARD=https://*.openshock.app
8 changes: 4 additions & 4 deletions .env.test
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PUBLIC_SITE_DOMAIN=openshock.dev
PUBLIC_SITE_SHORT_DOMAIN=openshock.dev
PUBLIC_BACKEND_API_DOMAIN=api.openshock.dev
PUBLIC_GATEWAY_CSP_WILDCARD=*.openshock.dev
PUBLIC_SITE_URL=https://openshock.dev
PUBLIC_SITE_SHORT_URL=https://openshock.dev
PUBLIC_BACKEND_API_URL=https://api.openshock.dev
PUBLIC_GATEWAY_CSP_WILDCARD=https://*.openshock.dev

PUBLIC_TURNSTILE_DEV_BYPASS_VALUE=dev-bypass
18 changes: 9 additions & 9 deletions src/lib/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PUBLIC_BACKEND_API_DOMAIN } from '$env/static/public';
import { PUBLIC_BACKEND_API_URL } from '$env/static/public';

import {
APITokensApi,
AccountApi as AccountV1Api,
Expand All @@ -22,17 +23,16 @@ import {
} from './internal/v2';

function GetBasePath() {
const domain = (PUBLIC_BACKEND_API_DOMAIN || undefined) as string | undefined;

if (!domain) {
return undefined;
if (!PUBLIC_BACKEND_API_URL) {
throw new Error('PUBLIC_BACKEND_API_URL is not set in the environment');
}

if (!/^[a-z0-9.-]+$/i.test(domain)) {
return undefined;
try {
const parsedUrl = new URL(PUBLIC_BACKEND_API_URL);
return parsedUrl.toString();
Comment thread
LucHeart marked this conversation as resolved.
Outdated
} catch (error: any) {
Comment thread
LucHeart marked this conversation as resolved.
throw new Error('PUBLIC_BACKEND_API_URL is not a valid URL', { cause: error });
}

return 'https://' + domain; // TODO: Add configurable protocol
}

function GetConfig(): ConfigurationParameters {
Expand Down
17 changes: 8 additions & 9 deletions src/lib/api/next/base.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import { PUBLIC_BACKEND_API_DOMAIN } from '$env/static/public';
import { PUBLIC_BACKEND_API_URL } from '$env/static/public';
import { ResponseError } from './ResponseError';

const BaseUrl = `https://${PUBLIC_BACKEND_API_DOMAIN}`;

type ApiVersion = 1 | 2;
export type Path = `/${ApiVersion}/${string}`;

export function GetBackendUrl(path: Path) {
return BaseUrl + path;
}
export type Path = `${ApiVersion}/${string}`;

export async function GetJson<T>(
path: Path,
expectedStatus = 200,
transformer: (data: unknown) => T
): Promise<T> {
const res = await fetch(BaseUrl + path, {
const res = await fetch(GetBackendUrl(path), {
Comment thread
LucHeart marked this conversation as resolved.
method: 'GET',
headers: { accept: 'application/json' },
credentials: 'include',
Expand All @@ -36,6 +30,11 @@ export async function GetJson<T>(
return transformer(data);
}

export function GetBackendUrl(path: Path): URL {
const url = new URL(path, PUBLIC_BACKEND_API_URL);
return url;
Comment thread
LucHeart marked this conversation as resolved.
}

export async function PostJson<T>(
path: Path,
body: unknown,
Expand Down
6 changes: 3 additions & 3 deletions src/lib/api/next/oauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import { TransformLoginOkResponse, TransformOAuthSignupData } from './transforme
export function GetOAuthAuthorizeUrl(provider: string, flow: 'LoginOrCreate' | 'Link') {
const providerEnc = encodeURIComponent(provider);
const flowEnc = encodeURIComponent(flow);
return GetBackendUrl(`/1/oauth/${providerEnc}/authorize?flow=${flowEnc}`);
return GetBackendUrl(`1/oauth/${providerEnc}/authorize?flow=${flowEnc}`);
}

export async function OAuthSignupGetData(provider: string) {
const providerEnc = encodeURIComponent(provider);
return GetJson<OAuthSignupData>(
`/1/oauth/${providerEnc}/signup-data`,
`1/oauth/${providerEnc}/signup-data`,
200,
TransformOAuthSignupData
);
Expand All @@ -23,7 +23,7 @@ export async function OAuthSignupFinalize(
): Promise<LoginOkResponse> {
const providerEnc = encodeURIComponent(provider);
return PostJson(
`/1/oauth/${providerEnc}/signup-finalize`,
`1/oauth/${providerEnc}/signup-finalize`,
payload,
200,
TransformLoginOkResponse
Expand Down
4 changes: 2 additions & 2 deletions src/lib/signalr/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
LogLevel,
} from '@microsoft/signalr';
import { dev } from '$app/environment';
import { PUBLIC_BACKEND_API_DOMAIN } from '$env/static/public';
import { PUBLIC_BACKEND_API_URL } from '$env/static/public';
import { toast } from 'svelte-sonner';
import { type Readable, get, writable } from 'svelte/store';
import {
Expand All @@ -31,7 +31,7 @@ export async function initializeSignalR() {

connection = new HubConnectionBuilder()
.configureLogging(dev ? LogLevel.Debug : LogLevel.Warning)
.withUrl(`https://${PUBLIC_BACKEND_API_DOMAIN}/1/hubs/user`, {
.withUrl(new URL(`1/hubs/user`, PUBLIC_BACKEND_API_URL).toString(), {
transport: HttpTransportType.WebSockets,
skipNegotiation: true,
})
Expand Down
4 changes: 2 additions & 2 deletions src/routes/(anonymous)/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PUBLIC_BACKEND_API_DOMAIN } from '$env/static/public';
import { PUBLIC_BACKEND_API_URL } from '$env/static/public';
import { Configuration, MetaApi } from '$lib/api/internal/v1';

type ResponseType = Promise<{ ok: false; error: string } | { ok: true; deviceCount: number }>;
Expand All @@ -16,7 +16,7 @@ export async function load({ setHeaders }): ResponseType {
try {
const metaApi = new MetaApi(
new Configuration({
basePath: 'https://' + PUBLIC_BACKEND_API_DOMAIN,
basePath: PUBLIC_BACKEND_API_URL,
headers: {
'User-Agent': 'OpenShockFrontend/1.0 (ServerSide)',
},
Expand Down
32 changes: 29 additions & 3 deletions svelte.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,28 @@ function getGitBranch() {
return child_process.execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
}

function getWsUrlFromHttpUrl(url) {
if (url.startsWith('https://')) {
return url.replace('https://', 'wss://');
} else if (url.startsWith('http://')) {
return url.replace('http://', 'ws://');
}

throw new Error(`Invalid URL was provided, it must start with http:// or https:// [${url}]`);
Comment thread
LucHeart marked this conversation as resolved.
}

function getSvelteBasePath() {
try {
const url = new URL(dotenv.PUBLIC_SITE_URL);
const path = url.pathname === '/' ? '' : url.pathname;
console.log(`Using base path: [${path}] from PUBLIC_SITE_URL: ${dotenv.PUBLIC_SITE_URL}`);
Comment thread Dismissed
return path;
} catch (error) {
throw new Error(`PUBLIC_SITE_URL is not a valid URL: ${error.message}`, { cause: error });
}

Comment thread
LucHeart marked this conversation as resolved.
}

const commitHash = getGitHash();
const branchName = getGitBranch();

Expand All @@ -49,6 +71,9 @@ const config = {
},
kit: {
adapter: adapter(),
paths: {
base: getSvelteBasePath()
},
csp: {
mode: 'hash',
directives: {
Expand All @@ -65,9 +90,10 @@ const config = {
],
'connect-src': [
'self',
'https://' + dotenv.PUBLIC_BACKEND_API_DOMAIN,
'wss://' + dotenv.PUBLIC_BACKEND_API_DOMAIN,
'wss://' + dotenv.PUBLIC_GATEWAY_CSP_WILDCARD,
dotenv.PUBLIC_BACKEND_API_URL,
getWsUrlFromHttpUrl(dotenv.PUBLIC_BACKEND_API_URL),
dotenv.PUBLIC_GATEWAY_CSP_WILDCARD,
getWsUrlFromHttpUrl(dotenv.PUBLIC_GATEWAY_CSP_WILDCARD),
'https://firmware.openshock.org',
'https://api.pwnedpasswords.com/range/',
'https://cloudflareinsights.com',
Expand Down
15 changes: 7 additions & 8 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,16 @@ function getPlugins(useLocalRedirect: boolean): PluginOption[] {
}

async function getServerConfig(mode: string, useLocalRedirect: boolean) {
if (!useLocalRedirect) return undefined;

const vars = { ...env, ...loadEnv(mode, process.cwd(), ['PUBLIC_']) };
const domain = vars.PUBLIC_SITE_DOMAIN;

// Load environment variables
if (!domain) {
printError('PUBLIC_SITE_DOMAIN must be set in your environment');
if(!vars.PUBLIC_SITE_URL) {
Comment thread
LucHeart marked this conversation as resolved.
printError('PUBLIC_SITE_URL must be set in your environment');
process.exit(1);
}

if (!useLocalRedirect) return undefined;

const domain = new URL(vars.PUBLIC_SITE_URL).hostname;

if (domain === 'localhost') {
return { host: 'localhost', port: 8080, proxy: {} };
}
Expand All @@ -93,7 +92,7 @@ export default defineConfig(async ({ command, mode, isPreview }) => {
const isLocalServe = command === 'serve' || isPreview === true;
const isProduction = mode === 'production' && (isTruthy(env.DOCKER) || isTruthy(env.CF_PAGES));

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

return defineConfig({
Expand Down