mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -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 { KyooErrors } from "./kyoo-errors";
|
||||
import { Account, TokenP, getCurrentApiUrl } from "./accounts";
|
||||
import { Account, Token, TokenP, getCurrentApiUrl } from "./accounts";
|
||||
import { UserP } from "./resources";
|
||||
import { addAccount, getCurrentAccount, removeAccounts, updateAccount } from "./account-internal";
|
||||
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;
|
||||
|
||||
export const getTokenWJ = async (account?: Account | null): ReturnType<typeof run> => {
|
||||
async function run() {
|
||||
if (account === undefined) account = getCurrentAccount();
|
||||
if (!account) return [null, null, null] as const;
|
||||
export const getTokenWJ = async (
|
||||
acc?: Account | null,
|
||||
forceRefresh: boolean = false,
|
||||
): 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;
|
||||
|
||||
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);
|
||||
try {
|
||||
token = await queryFn(
|
||||
@ -121,9 +126,11 @@ export const getTokenWJ = async (account?: Account | null): ReturnType<typeof ru
|
||||
// Do not cache promise durring ssr.
|
||||
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();
|
||||
const ret = await running;
|
||||
running_id = null;
|
||||
running = null;
|
||||
return ret;
|
||||
};
|
||||
|
@ -28,7 +28,7 @@ import {
|
||||
import { z } from "zod";
|
||||
import { KyooErrors } from "./kyoo-errors";
|
||||
import { Page, Paged } from "./page";
|
||||
import { getToken } from "./login";
|
||||
import { getToken, getTokenWJ } from "./login";
|
||||
import { getCurrentApiUrl } from ".";
|
||||
|
||||
export let lastUsedUrl: string = null!;
|
||||
@ -48,12 +48,13 @@ export const queryFn = async <Parser extends z.ZodTypeAny>(
|
||||
} & Partial<QueryFunctionContext>)
|
||||
),
|
||||
type?: Parser,
|
||||
token?: string | null,
|
||||
iToken?: string | null,
|
||||
): Promise<z.infer<Parser>> => {
|
||||
const url = context.apiUrl && context.apiUrl.length > 0 ? context.apiUrl : getCurrentApiUrl();
|
||||
lastUsedUrl = url!;
|
||||
|
||||
if (token === undefined && context.authenticated !== false) token = await getToken();
|
||||
const token =
|
||||
iToken === undefined && context.authenticated !== false ? await getToken() : undefined;
|
||||
const path = [url]
|
||||
.concat(
|
||||
"path" in context
|
||||
@ -90,6 +91,14 @@ export const queryFn = async <Parser extends z.ZodTypeAny>(
|
||||
if (resp.status === 404) {
|
||||
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) {
|
||||
const error = await resp.text();
|
||||
let data;
|
||||
@ -128,7 +137,7 @@ export const queryFn = async <Parser extends z.ZodTypeAny>(
|
||||
errors: [
|
||||
"Invalid response from kyoo. Possible version mismatch between the server and the application.",
|
||||
],
|
||||
status: "parse"
|
||||
status: "parse",
|
||||
} as KyooErrors;
|
||||
}
|
||||
return parsed.data;
|
||||
|
Loading…
x
Reference in New Issue
Block a user