mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-06-23 15:30:34 -04:00
Refresh token to check if user was verifed after a 403
This commit is contained in:
parent
5f936d36b1
commit
8ee4446b30
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
import { queryFn } from "./query";
|
import { queryFn } from "./query";
|
||||||
import { KyooErrors } from "./kyoo-errors";
|
import { KyooErrors } from "./kyoo-errors";
|
||||||
import { Account, TokenP, getCurrentApiUrl } from "./accounts";
|
import { Account, Token, TokenP, getCurrentApiUrl } from "./accounts";
|
||||||
import { UserP } from "./resources";
|
import { UserP } from "./resources";
|
||||||
import { addAccount, getCurrentAccount, removeAccounts, updateAccount } from "./account-internal";
|
import { addAccount, getCurrentAccount, removeAccounts, updateAccount } from "./account-internal";
|
||||||
import { Platform } from "react-native";
|
import { Platform } from "react-native";
|
||||||
@ -88,16 +88,21 @@ export const oidcLogin = async (provider: string, code: string, apiUrl?: string)
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let running_id: string | null = null;
|
||||||
let running: ReturnType<typeof getTokenWJ> | null = null;
|
let running: ReturnType<typeof getTokenWJ> | null = null;
|
||||||
|
|
||||||
export const getTokenWJ = async (account?: Account | null): ReturnType<typeof run> => {
|
export const getTokenWJ = async (
|
||||||
async function run() {
|
acc?: Account | null,
|
||||||
if (account === undefined) account = getCurrentAccount();
|
forceRefresh: boolean = false,
|
||||||
if (!account) return [null, null, null] as const;
|
): Promise<readonly [string, Token, null] | readonly [null, null, KyooErrors | null]> => {
|
||||||
|
if (acc === undefined) acc = getCurrentAccount();
|
||||||
|
if (!acc) return [null, null, null] as const;
|
||||||
|
const account = acc;
|
||||||
|
|
||||||
|
async function run() {
|
||||||
let token = account.token;
|
let token = account.token;
|
||||||
|
|
||||||
if (account.token.expire_at <= new Date(new Date().getTime() + 10 * 1000)) {
|
if (forceRefresh || account.token.expire_at <= new Date(new Date().getTime() + 10 * 1000)) {
|
||||||
console.log("refreshing token for account", account.slug);
|
console.log("refreshing token for account", account.slug);
|
||||||
try {
|
try {
|
||||||
token = await queryFn(
|
token = await queryFn(
|
||||||
@ -121,9 +126,11 @@ export const getTokenWJ = async (account?: Account | null): ReturnType<typeof ru
|
|||||||
// Do not cache promise durring ssr.
|
// Do not cache promise durring ssr.
|
||||||
if (Platform.OS === "web" && typeof window === "undefined") return await run();
|
if (Platform.OS === "web" && typeof window === "undefined") return await run();
|
||||||
|
|
||||||
if (running) return await running;
|
if (running && running_id === account.id) return await running;
|
||||||
|
running_id = account.id;
|
||||||
running = run();
|
running = run();
|
||||||
const ret = await running;
|
const ret = await running;
|
||||||
|
running_id = null;
|
||||||
running = null;
|
running = null;
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
@ -28,7 +28,7 @@ import {
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { KyooErrors } from "./kyoo-errors";
|
import { KyooErrors } from "./kyoo-errors";
|
||||||
import { Page, Paged } from "./page";
|
import { Page, Paged } from "./page";
|
||||||
import { getToken } from "./login";
|
import { getToken, getTokenWJ } from "./login";
|
||||||
import { getCurrentApiUrl } from ".";
|
import { getCurrentApiUrl } from ".";
|
||||||
|
|
||||||
export let lastUsedUrl: string = null!;
|
export let lastUsedUrl: string = null!;
|
||||||
@ -48,12 +48,13 @@ export const queryFn = async <Parser extends z.ZodTypeAny>(
|
|||||||
} & Partial<QueryFunctionContext>)
|
} & Partial<QueryFunctionContext>)
|
||||||
),
|
),
|
||||||
type?: Parser,
|
type?: Parser,
|
||||||
token?: string | null,
|
iToken?: string | null,
|
||||||
): Promise<z.infer<Parser>> => {
|
): Promise<z.infer<Parser>> => {
|
||||||
const url = context.apiUrl && context.apiUrl.length > 0 ? context.apiUrl : getCurrentApiUrl();
|
const url = context.apiUrl && context.apiUrl.length > 0 ? context.apiUrl : getCurrentApiUrl();
|
||||||
lastUsedUrl = url!;
|
lastUsedUrl = url!;
|
||||||
|
|
||||||
if (token === undefined && context.authenticated !== false) token = await getToken();
|
const token =
|
||||||
|
iToken === undefined && context.authenticated !== false ? await getToken() : undefined;
|
||||||
const path = [url]
|
const path = [url]
|
||||||
.concat(
|
.concat(
|
||||||
"path" in context
|
"path" in context
|
||||||
@ -90,6 +91,14 @@ export const queryFn = async <Parser extends z.ZodTypeAny>(
|
|||||||
if (resp.status === 404) {
|
if (resp.status === 404) {
|
||||||
throw { errors: ["Resource not found."], status: 404 } as KyooErrors;
|
throw { errors: ["Resource not found."], status: 404 } as KyooErrors;
|
||||||
}
|
}
|
||||||
|
// If we got a forbidden, try to refresh the token
|
||||||
|
// if we got a token as an argument, it either means we already retried or we go one provided that's fresh
|
||||||
|
// so we can't retry either ways.
|
||||||
|
if (resp.status === 403 && iToken === undefined && token) {
|
||||||
|
const [newToken, _, error] = await getTokenWJ(undefined, true);
|
||||||
|
if (newToken) return await queryFn(context, type, newToken);
|
||||||
|
else console.error("refresh error while retrying a forbidden", error);
|
||||||
|
}
|
||||||
if (!resp.ok) {
|
if (!resp.ok) {
|
||||||
const error = await resp.text();
|
const error = await resp.text();
|
||||||
let data;
|
let data;
|
||||||
@ -128,7 +137,7 @@ export const queryFn = async <Parser extends z.ZodTypeAny>(
|
|||||||
errors: [
|
errors: [
|
||||||
"Invalid response from kyoo. Possible version mismatch between the server and the application.",
|
"Invalid response from kyoo. Possible version mismatch between the server and the application.",
|
||||||
],
|
],
|
||||||
status: "parse"
|
status: "parse",
|
||||||
} as KyooErrors;
|
} as KyooErrors;
|
||||||
}
|
}
|
||||||
return parsed.data;
|
return parsed.data;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user