mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-05-24 02:02:36 -04:00
wip: Replace the secure store
This commit is contained in:
parent
fee59833f2
commit
1237a9157c
@ -40,6 +40,7 @@
|
||||
"react-dom": "18.2.0",
|
||||
"react-i18next": "^12.2.0",
|
||||
"react-native": "0.71.8",
|
||||
"react-native-mmkv": "^2.10.1",
|
||||
"react-native-reanimated": "~2.14.4",
|
||||
"react-native-safe-area-context": "4.5.0",
|
||||
"react-native-screens": "~3.20.0",
|
||||
|
@ -24,7 +24,7 @@ import { Hydrate, QueryClientProvider } from "@tanstack/react-query";
|
||||
import { HiddenIfNoJs, SkeletonCss, ThemeSelector } from "@kyoo/primitives";
|
||||
import { WebTooltip } from "@kyoo/primitives/src/tooltip.web";
|
||||
import { createQueryClient, fetchQuery, getTokenWJ, QueryIdentifier, QueryPage } from "@kyoo/models";
|
||||
import { setSecureItemSync } from "@kyoo/models/src/secure-store.web";
|
||||
import { setSecureItem } from "@kyoo/models/src/secure-store.web";
|
||||
import { useState } from "react";
|
||||
import NextApp, { AppContext, type AppProps } from "next/app";
|
||||
import { Poppins } from "next/font/google";
|
||||
@ -101,7 +101,7 @@ const App = ({ Component, pageProps }: AppProps) => {
|
||||
|
||||
// Set the auth from the server (if the token was refreshed during SSR).
|
||||
if (typeof window !== "undefined" && token)
|
||||
setSecureItemSync("auth", JSON.stringify(token));
|
||||
setSecureItem("auth", JSON.stringify(token));
|
||||
|
||||
return (
|
||||
<YoshikiDebug>
|
||||
|
@ -5,7 +5,7 @@
|
||||
"packageManager": "yarn@3.2.4",
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.0.28",
|
||||
"expo-secure-store": "^12.1.1",
|
||||
"react-native-mmkv": "^2.10.1",
|
||||
"typescript": "^4.9.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
@ -42,33 +42,31 @@ type Result<A, B> =
|
||||
export type Account = Token & { apiUrl: string; username: string };
|
||||
|
||||
export const useAccounts = () => {
|
||||
const [accounts, setAccounts] = useState<Account[]>([]);
|
||||
const [selected, setSelected] = useState(0);
|
||||
const [accounts] = useState<Account[]>(JSON.parse(getSecureItem("accounts") ?? "[]"));
|
||||
const [selected, setSelected] = useState<number>(parseInt(getSecureItem("selected") ?? "0"));
|
||||
|
||||
useEffect(() => {
|
||||
async function run() {
|
||||
setAccounts(JSON.parse(await getSecureItem("accounts") ?? "[]"));
|
||||
}
|
||||
return {
|
||||
accounts,
|
||||
selected,
|
||||
setSelected: (selected: number) => {
|
||||
setSelected(selected);
|
||||
setSecureItem("selected", selected.toString());
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
run();
|
||||
}, []);
|
||||
return {accounts, selected, setSelected};
|
||||
}
|
||||
|
||||
const addAccount = async (token: Token, apiUrl: string, username: string | null): Promise<void> => {
|
||||
const accounts: Account[] = JSON.parse(await getSecureItem("accounts") ?? "[]");
|
||||
const accIdx = accounts.findIndex(x => x.refresh_token === token.refresh_token);
|
||||
if (accIdx === -1)
|
||||
accounts.push({...token, username, apiUrl});
|
||||
else
|
||||
accounts[accIdx] = {...accounts[accIdx], ...token};
|
||||
await setSecureItem("accounts", JSON.stringify(accounts));
|
||||
}
|
||||
const addAccount = (token: Token, apiUrl: string, username: string | null) => {
|
||||
const accounts: Account[] = JSON.parse(getSecureItem("accounts") ?? "[]");
|
||||
const accIdx = accounts.findIndex((x) => x.refresh_token === token.refresh_token);
|
||||
if (accIdx === -1) accounts.push({ ...token, username: username!, apiUrl });
|
||||
else accounts[accIdx] = { ...accounts[accIdx], ...token };
|
||||
setSecureItem("accounts", JSON.stringify(accounts));
|
||||
};
|
||||
|
||||
export const loginFunc = async (
|
||||
action: "register" | "login" | "refresh",
|
||||
body: { username: string, password: string, email?: string } | string,
|
||||
apiUrl?: string
|
||||
body: { username: string; password: string; email?: string } | string,
|
||||
apiUrl?: string,
|
||||
): Promise<Result<Token, string>> => {
|
||||
try {
|
||||
const token = await queryFn(
|
||||
@ -107,23 +105,23 @@ export const getTokenWJ = async (cookies?: string): Promise<[string, Token] | [n
|
||||
};
|
||||
|
||||
export const getToken = async (cookies?: string): Promise<string | null> =>
|
||||
(await getTokenWJ(cookies))[0]
|
||||
(await getTokenWJ(cookies))[0];
|
||||
|
||||
export const logout = async () =>{
|
||||
export const logout = async () => {
|
||||
if (Platform.OS !== "web") {
|
||||
const tokenStr = await getSecureItem("auth");
|
||||
if (!tokenStr) return;
|
||||
const token = TokenP.parse(JSON.parse(tokenStr));
|
||||
|
||||
let accounts: Account[] = JSON.parse(await getSecureItem("accounts") ?? "[]");
|
||||
accounts = accounts.filter(x => x.refresh_token !== token.refresh_token);
|
||||
let accounts: Account[] = JSON.parse((await getSecureItem("accounts")) ?? "[]");
|
||||
accounts = accounts.filter((x) => x.refresh_token !== token.refresh_token);
|
||||
await setSecureItem("accounts", JSON.stringify(accounts));
|
||||
}
|
||||
|
||||
await deleteSecureItem("auth")
|
||||
}
|
||||
await deleteSecureItem("auth");
|
||||
};
|
||||
|
||||
export const deleteAccount = async () => {
|
||||
await queryFn({ path: ["auth", "me"], method: "DELETE"});
|
||||
await queryFn({ path: ["auth", "me"], method: "DELETE" });
|
||||
await logout();
|
||||
}
|
||||
};
|
||||
|
@ -18,8 +18,19 @@
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export {
|
||||
setItemAsync as setSecureItem,
|
||||
deleteItemAsync as deleteSecureItem,
|
||||
getItemAsync as getSecureItem,
|
||||
} from "expo-secure-store";
|
||||
import { MMKV } from 'react-native-mmkv'
|
||||
|
||||
const storage = new MMKV();
|
||||
|
||||
export const setSecureItem = (key: string, value: string | null) => {
|
||||
if (value === null)
|
||||
storage.delete(key);
|
||||
else
|
||||
storage.set(key, value);
|
||||
}
|
||||
|
||||
export const deleteSecureItem = (key: string) => setSecureItem(key, null);
|
||||
|
||||
export const getSecureItem = (key: string, _cookies?: string): string | null => {
|
||||
return storage.getString(key) || null;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@
|
||||
* along with Kyoo. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
export const setSecureItemSync = (key: string, value: string | null) => {
|
||||
export const setSecureItem = (key: string, value: string | null) => {
|
||||
const d = new Date();
|
||||
// A year
|
||||
d.setTime(d.getTime() + 365 * 24 * 60 * 60 * 1000);
|
||||
@ -27,12 +27,9 @@ export const setSecureItemSync = (key: string, value: string | null) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const setSecureItem = async (key: string, value: string | null): Promise<null> =>
|
||||
setSecureItemSync(key, value);
|
||||
export const deleteSecureItem = (key: string) => setSecureItem(key, null);
|
||||
|
||||
export const deleteSecureItem = async (key: string) => setSecureItem(key, null);
|
||||
|
||||
export const getSecureItem = async (key: string, cookies?: string): Promise<string | null> => {
|
||||
export const getSecureItem = (key: string, cookies?: string): string | null => {
|
||||
// Don't try to use document's cookies on SSR.
|
||||
if (!cookies && typeof window === "undefined") return null;
|
||||
const name = key + "=";
|
||||
|
@ -2263,7 +2263,7 @@ __metadata:
|
||||
resolution: "@kyoo/models@workspace:packages/models"
|
||||
dependencies:
|
||||
"@types/react": ^18.0.28
|
||||
expo-secure-store: ^12.1.1
|
||||
react-native-mmkv: ^2.10.1
|
||||
typescript: ^4.9.5
|
||||
zod: ^3.21.4
|
||||
peerDependencies:
|
||||
@ -6907,7 +6907,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"expo-secure-store@npm:^12.1.1, expo-secure-store@npm:~12.1.1":
|
||||
"expo-secure-store@npm:~12.1.1":
|
||||
version: 12.1.1
|
||||
resolution: "expo-secure-store@npm:12.1.1"
|
||||
peerDependencies:
|
||||
@ -10339,6 +10339,7 @@ __metadata:
|
||||
react-dom: 18.2.0
|
||||
react-i18next: ^12.2.0
|
||||
react-native: 0.71.8
|
||||
react-native-mmkv: ^2.10.1
|
||||
react-native-reanimated: ~2.14.4
|
||||
react-native-safe-area-context: 4.5.0
|
||||
react-native-screens: ~3.20.0
|
||||
@ -11678,6 +11679,16 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-native-mmkv@npm:^2.10.1":
|
||||
version: 2.10.1
|
||||
resolution: "react-native-mmkv@npm:2.10.1"
|
||||
peerDependencies:
|
||||
react: "*"
|
||||
react-native: ">=0.71.0"
|
||||
checksum: 2db42a667acd104047ddf307e852ffd9d9c6302454364fcc4cd35d8510d6f500bcd3562e14d95ae7fd520eac1cd3cc8a239c539a7339b70a4e6fd2d3f70daee7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-native-reanimated@npm:2.14.4, react-native-reanimated@npm:~2.14.4":
|
||||
version: 2.14.4
|
||||
resolution: "react-native-reanimated@npm:2.14.4"
|
||||
|
Loading…
x
Reference in New Issue
Block a user