1 changed files with 125 additions and 0 deletions
@ -0,0 +1,125 @@ |
|||||||
|
import { useCallback } from "react"; |
||||||
|
|
||||||
|
import { SessionResponse } from "@/backend/accounts/auth"; |
||||||
|
import { bookmarkMediaToInput } from "@/backend/accounts/bookmarks"; |
||||||
|
import { |
||||||
|
base64ToBuffer, |
||||||
|
bytesToBase64, |
||||||
|
bytesToBase64Url, |
||||||
|
encryptData, |
||||||
|
keysFromMnemonic, |
||||||
|
keysFromSeed, |
||||||
|
signChallenge, |
||||||
|
} from "@/backend/accounts/crypto"; |
||||||
|
import { importBookmarks, importProgress } from "@/backend/accounts/import"; |
||||||
|
import { getLoginChallengeToken, loginAccount } from "@/backend/accounts/login"; |
||||||
|
import { progressMediaItemToInputs } from "@/backend/accounts/progress"; |
||||||
|
import { |
||||||
|
getRegisterChallengeToken, |
||||||
|
registerAccount, |
||||||
|
} from "@/backend/accounts/register"; |
||||||
|
import { removeSession } from "@/backend/accounts/sessions"; |
||||||
|
import { getSettings } from "@/backend/accounts/settings"; |
||||||
|
import { |
||||||
|
UserResponse, |
||||||
|
getBookmarks, |
||||||
|
getProgress, |
||||||
|
getUser, |
||||||
|
} from "@/backend/accounts/user"; |
||||||
|
import { useAuthData } from "@/hooks/auth/useAuthData"; |
||||||
|
import { useBackendUrl } from "@/hooks/auth/useBackendUrl"; |
||||||
|
import { AccountWithToken, useAuthStore } from "@/stores/auth"; |
||||||
|
import { BookmarkMediaItem, useBookmarkStore } from "@/stores/bookmarks"; |
||||||
|
import { ProgressMediaItem, useProgressStore } from "@/stores/progress"; |
||||||
|
|
||||||
|
export interface RegistrationData { |
||||||
|
recaptchaToken?: string; |
||||||
|
mnemonic: string; |
||||||
|
userData: { |
||||||
|
device: string; |
||||||
|
profile: { |
||||||
|
colorA: string; |
||||||
|
colorB: string; |
||||||
|
icon: string; |
||||||
|
}; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export interface LoginData { |
||||||
|
mnemonic: string; |
||||||
|
userData: { |
||||||
|
device: string; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
export function useMigration() { |
||||||
|
const currentAccount = useAuthStore((s) => s.account); |
||||||
|
const progress = useProgressStore((s) => s.items); |
||||||
|
const bookmarks = useBookmarkStore((s) => s.bookmarks); |
||||||
|
const { login: userDataLogin } = useAuthData(); |
||||||
|
|
||||||
|
const importData = async ( |
||||||
|
backendUrl: string, |
||||||
|
account: AccountWithToken, |
||||||
|
progressItems: Record<string, ProgressMediaItem>, |
||||||
|
bookmarkItems: Record<string, BookmarkMediaItem>, |
||||||
|
) => { |
||||||
|
if ( |
||||||
|
Object.keys(progressItems).length === 0 && |
||||||
|
Object.keys(bookmarkItems).length === 0 |
||||||
|
) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
const progressInputs = Object.entries(progressItems).flatMap( |
||||||
|
([tmdbId, item]) => progressMediaItemToInputs(tmdbId, item), |
||||||
|
); |
||||||
|
|
||||||
|
const bookmarkInputs = Object.entries(bookmarkItems).map(([tmdbId, item]) => |
||||||
|
bookmarkMediaToInput(tmdbId, item), |
||||||
|
); |
||||||
|
|
||||||
|
await Promise.all([ |
||||||
|
importProgress(backendUrl, account, progressInputs), |
||||||
|
importBookmarks(backendUrl, account, bookmarkInputs), |
||||||
|
]); |
||||||
|
}; |
||||||
|
|
||||||
|
const migrate = useCallback( |
||||||
|
async (backendUrl: string, recaptchaToken: string) => { |
||||||
|
if (!currentAccount) return; |
||||||
|
|
||||||
|
const { challenge } = await getRegisterChallengeToken( |
||||||
|
backendUrl, |
||||||
|
recaptchaToken, |
||||||
|
); |
||||||
|
const keys = await keysFromSeed(base64ToBuffer(currentAccount.seed)); |
||||||
|
const signature = await signChallenge(keys, challenge); |
||||||
|
const registerResult = await registerAccount(backendUrl, { |
||||||
|
challenge: { |
||||||
|
code: challenge, |
||||||
|
signature, |
||||||
|
}, |
||||||
|
publicKey: bytesToBase64Url(keys.publicKey), |
||||||
|
device: await encryptData(currentAccount.deviceName, keys.seed), |
||||||
|
profile: currentAccount.profile, |
||||||
|
}); |
||||||
|
|
||||||
|
const account = await userDataLogin( |
||||||
|
registerResult, |
||||||
|
registerResult.user, |
||||||
|
registerResult.session, |
||||||
|
bytesToBase64(keys.seed), |
||||||
|
); |
||||||
|
|
||||||
|
await importData(backendUrl, account, progress, bookmarks); |
||||||
|
|
||||||
|
return account; |
||||||
|
}, |
||||||
|
[currentAccount, userDataLogin, bookmarks, progress], |
||||||
|
); |
||||||
|
|
||||||
|
return { |
||||||
|
migrate, |
||||||
|
}; |
||||||
|
} |
Loading…
Reference in new issue