diff --git a/front/packages/models/src/account-internal.ts b/front/packages/models/src/account-internal.ts
new file mode 100644
index 00000000..b5b97a9d
--- /dev/null
+++ b/front/packages/models/src/account-internal.ts
@@ -0,0 +1,110 @@
+/*
+ * Kyoo - A portable and vast media library solution.
+ * Copyright (c) Kyoo.
+ *
+ * See AUTHORS.md and LICENSE file in the project root for full license information.
+ *
+ * Kyoo is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * Kyoo is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Kyoo. If not, see .
+ */
+
+import { z } from "zod";
+import { Account, AccountP } from "./accounts";
+import { MMKV } from "react-native-mmkv";
+
+const storage = new MMKV();
+
+const readAccounts = () => {
+ const acc = storage.getString("accounts");
+ if (!acc) return [];
+ return z.array(AccountP).parse(JSON.parse(acc));
+};
+
+const writeAccounts = (accounts: Account[]) => {
+ storage.set("accounts", JSON.stringify(accounts));
+};
+
+export const setAccountCookie = (account?: Account) => {
+ const value = JSON.stringify(account);
+ // Remove illegal values from json. There should not be one in the account anyways.
+ value.replaceAll(";", "");
+ const d = new Date();
+ // A year
+ d.setTime(d.getTime() + 365 * 24 * 60 * 60 * 1000);
+ const expires = value ? "expires=" + d.toUTCString() : "expires=Thu, 01 Jan 1970 00:00:01 GMT";
+ document.cookie = "account=" + value + ";" + expires + ";path=/";
+ return null;
+}
+
+export const readAccountCookie = (cookies?: string) => {
+ if (!cookies) return null;
+ const name = "account=";
+ const decodedCookie = decodeURIComponent(cookies);
+ const ca = decodedCookie.split(";");
+ for (let i = 0; i < ca.length; i++) {
+ let c = ca[i];
+ while (c.charAt(0) == " ") {
+ c = c.substring(1);
+ }
+ if (c.indexOf(name) == 0) {
+ const str = c.substring(name.length, c.length);
+ return AccountP.parse(JSON.parse(str));
+ }
+ }
+ return null;
+}
+
+export const getCurrentAccount = () => {
+ const accounts = readAccounts();
+ return accounts.find(x => x.selected);
+}
+
+export const addAccount = (account: Account) => {
+ const accounts = readAccounts();
+
+ // Prevent the user from adding the same account twice.
+ if (accounts.find(x => x.id == account.id)) {
+ updateAccount(account.id, account);
+ return;
+ }
+
+ for (const acc of accounts) acc.selected = false;
+ accounts.push(account);
+ writeAccounts(accounts);
+};
+
+export const removeAccounts = (filter: (acc: Account) => boolean) => {
+ let accounts = readAccounts();
+ accounts = accounts.filter(filter);
+ if (!accounts.find((x) => x.selected) && accounts.length > 0) {
+ accounts[0].selected = true;
+ }
+ writeAccounts(accounts);
+};
+
+export const updateAccount = (id: string, account: Account) => {
+ const accounts = readAccounts();
+ const idx = accounts.findIndex((x) => x.id == id);
+ if (idx === -1) return;
+
+ if (account.selected) {
+ for (const acc of accounts) acc.selected = false;
+ } else if(accounts[idx].selected) {
+ // we just unselected the current account, focus another one.
+ if (accounts.length > 0)
+ accounts[0].selected = true
+ }
+
+ accounts[idx] = account;
+ writeAccounts(accounts);
+};
diff --git a/front/packages/models/src/secure-store.ts b/front/packages/models/src/secure-store.ts
deleted file mode 100644
index 7a2886f0..00000000
--- a/front/packages/models/src/secure-store.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Kyoo - A portable and vast media library solution.
- * Copyright (c) Kyoo.
- *
- * See AUTHORS.md and LICENSE file in the project root for full license information.
- *
- * Kyoo is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * Kyoo is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Kyoo. If not, see .
- */
-
-import { MMKV } from "react-native-mmkv";
-
-export 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;
-};
diff --git a/front/packages/models/src/secure-store.web.ts b/front/packages/models/src/secure-store.web.ts
deleted file mode 100644
index 275a909e..00000000
--- a/front/packages/models/src/secure-store.web.ts
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Kyoo - A portable and vast media library solution.
- * Copyright (c) Kyoo.
- *
- * See AUTHORS.md and LICENSE file in the project root for full license information.
- *
- * Kyoo is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * any later version.
- *
- * Kyoo is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Kyoo. If not, see .
- */
-
-export const setSecureItem = (key: string, value: string | null) => {
- const d = new Date();
- // A year
- d.setTime(d.getTime() + 365 * 24 * 60 * 60 * 1000);
- const expires = value ? "expires=" + d.toUTCString() : "expires=Thu, 01 Jan 1970 00:00:01 GMT";
- document.cookie = key + "=" + value + ";" + expires + ";path=/";
- return null;
-};
-
-export const deleteSecureItem = (key: string) => setSecureItem(key, 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 + "=";
- const decodedCookie = decodeURIComponent(cookies ?? document.cookie);
- const ca = decodedCookie.split(";");
- for (let i = 0; i < ca.length; i++) {
- let c = ca[i];
- while (c.charAt(0) == " ") {
- c = c.substring(1);
- }
- if (c.indexOf(name) == 0) {
- return c.substring(name.length, c.length);
- }
- }
- return null;
-};