All checks were successful
Queue Release Build / prepare (push) Successful in 19s
Deploy Web Apps / deploy (push) Successful in 8m12s
Queue Release Build / build-windows (push) Successful in 27m44s
Queue Release Build / build-linux (push) Successful in 48m1s
Queue Release Build / build-android (push) Successful in 22m7s
Queue Release Build / finalize (push) Successful in 2m42s
107 lines
2.9 KiB
TypeScript
107 lines
2.9 KiB
TypeScript
import { type APIRequestContext, type Page } from '@playwright/test';
|
|
|
|
export const AUTH_TOKENS_STORAGE_KEY = 'metoyou.authTokens';
|
|
export const SIGNAL_SERVER_CREDENTIALS_STORAGE_KEY = 'metoyou.signalServerCredentials';
|
|
|
|
export interface AuthSession {
|
|
id: string;
|
|
username: string;
|
|
displayName: string;
|
|
token: string;
|
|
expiresAt: number;
|
|
}
|
|
|
|
export function authHeaders(token: string): Record<string, string> {
|
|
return {
|
|
Authorization: `Bearer ${token}`,
|
|
'Content-Type': 'application/json'
|
|
};
|
|
}
|
|
|
|
export async function registerTestUser(
|
|
request: APIRequestContext,
|
|
baseUrl: string,
|
|
username: string,
|
|
password: string,
|
|
displayName?: string
|
|
): Promise<AuthSession> {
|
|
const response = await request.post(`${baseUrl}/api/users/register`, {
|
|
data: {
|
|
username,
|
|
password,
|
|
displayName: displayName ?? username
|
|
}
|
|
});
|
|
|
|
if (!response.ok()) {
|
|
throw new Error(`Failed to register test user ${username}: ${response.status()} ${await response.text()}`);
|
|
}
|
|
|
|
return await response.json() as AuthSession;
|
|
}
|
|
|
|
export async function loginTestUser(
|
|
request: APIRequestContext,
|
|
baseUrl: string,
|
|
username: string,
|
|
password: string
|
|
): Promise<AuthSession> {
|
|
const response = await request.post(`${baseUrl}/api/users/login`, {
|
|
data: { username, password }
|
|
});
|
|
|
|
if (!response.ok()) {
|
|
throw new Error(`Failed to login test user ${username}: ${response.status()} ${await response.text()}`);
|
|
}
|
|
|
|
return await response.json() as AuthSession;
|
|
}
|
|
|
|
export async function readSignalServerCredentialFromPage(
|
|
page: Page,
|
|
serverUrl: string
|
|
): Promise<{ userId: string; token: string; username: string } | null> {
|
|
return await page.evaluate(({ storageKey, url }) => {
|
|
try {
|
|
const store = JSON.parse(localStorage.getItem(storageKey) || '{}') as Record<string, {
|
|
userId: string;
|
|
token: string;
|
|
username: string;
|
|
expiresAt: number;
|
|
}>;
|
|
const normalizedUrl = url.trim().replace(/\/+$/, '');
|
|
const entry = store[normalizedUrl];
|
|
|
|
if (!entry || entry.expiresAt <= Date.now()) {
|
|
return null;
|
|
}
|
|
|
|
return {
|
|
userId: entry.userId,
|
|
token: entry.token,
|
|
username: entry.username
|
|
};
|
|
} catch {
|
|
return null;
|
|
}
|
|
}, { storageKey: SIGNAL_SERVER_CREDENTIALS_STORAGE_KEY, url: serverUrl });
|
|
}
|
|
|
|
export async function readAuthTokenFromPage(page: Page, serverUrl: string): Promise<string | null> {
|
|
return await page.evaluate(({ storageKey, url }) => {
|
|
try {
|
|
const store = JSON.parse(localStorage.getItem(storageKey) || '{}') as Record<string, { token: string; expiresAt: number }>;
|
|
const normalizedUrl = url.trim().replace(/\/+$/, '');
|
|
const entry = store[normalizedUrl];
|
|
|
|
if (!entry || entry.expiresAt <= Date.now()) {
|
|
return null;
|
|
}
|
|
|
|
return entry.token;
|
|
} catch {
|
|
return null;
|
|
}
|
|
}, { storageKey: AUTH_TOKENS_STORAGE_KEY, url: serverUrl });
|
|
}
|