mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 15:08:47 -07:00
fix(site): parse return paths as URLs; refresh account state after changes
- localPath resolves the path against this origin, so control characters or backslashes can't turn it into another site's address. - link, sign-out and unlink drop the cached account answer.
This commit is contained in:
@@ -22,8 +22,15 @@ export function getMe(fresh = false): Promise<AccountMe> {
|
|||||||
/** `url` if it is a path on this site, else `/` (the server applies the same
|
/** `url` if it is a path on this site, else `/` (the server applies the same
|
||||||
* rule): never navigate to an address taken from the query string otherwise. */
|
* rule): never navigate to an address taken from the query string otherwise. */
|
||||||
export function localPath(url: string | null | undefined): string {
|
export function localPath(url: string | null | undefined): string {
|
||||||
if (!url || !url.startsWith('/') || url.startsWith('//') || url.startsWith('/\\')) return '/';
|
if (!url || !url.startsWith('/')) return '/';
|
||||||
return url;
|
// Parse it the way the browser will (it drops tabs and newlines and reads
|
||||||
|
// \ as /) and keep it only if it stays on this origin.
|
||||||
|
try {
|
||||||
|
const u = new URL(url, window.location.origin);
|
||||||
|
return u.origin === window.location.origin ? u.pathname + u.search + u.hash : '/';
|
||||||
|
} catch {
|
||||||
|
return '/';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Starts sign-in at the provider; comes back to `returnUrl` on this site. */
|
/** Starts sign-in at the provider; comes back to `returnUrl` on this site. */
|
||||||
@@ -31,10 +38,17 @@ export function signInUrl(returnUrl = window.location.pathname + window.location
|
|||||||
return `/api/auth/external/login?returnUrl=${encodeURIComponent(returnUrl)}`;
|
return `/api/auth/external/login?returnUrl=${encodeURIComponent(returnUrl)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Each of these changes who is signed in, so the cached answer is dropped.
|
||||||
|
async function changesAccount<T>(request: Promise<T>): Promise<T> {
|
||||||
|
const result = await request;
|
||||||
|
cached = null;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
export const link = (username: string, password: string) =>
|
export const link = (username: string, password: string) =>
|
||||||
post<{ linked: boolean; username: string }>('/account/link', { username, password });
|
changesAccount(post<{ linked: boolean; username: string }>('/account/link', { username, password }));
|
||||||
export const signOut = () => post('/account/logout', {});
|
export const signOut = () => changesAccount(post('/account/logout', {}));
|
||||||
export const unlink = () => post('/account/unlink', {});
|
export const unlink = () => changesAccount(post('/account/unlink', {}));
|
||||||
|
|
||||||
// Server error code -> friendly copy.
|
// Server error code -> friendly copy.
|
||||||
export const LINK_ERRORS: Record<string, string> = {
|
export const LINK_ERRORS: Record<string, string> = {
|
||||||
|
|||||||
Reference in New Issue
Block a user