2024-06-30 17:41:56 +05:30

190 lines
4.8 KiB
TypeScript

import { apiURL } from "@/next/origins";
import { appName } from "@/next/types/app";
import type {
RecoveryKey,
TwoFactorRecoveryResponse,
TwoFactorSecret,
TwoFactorVerificationResponse,
UserVerificationResponse,
} from "@ente/accounts/types/user";
import type { B64EncryptionResult } from "@ente/shared/crypto/internal/libsodium";
import { ApiError, CustomError } from "@ente/shared/error";
import HTTPService from "@ente/shared/network/HTTPService";
import { getToken } from "@ente/shared/storage/localStorage/helpers";
import type { KeyAttributes } from "@ente/shared/user/types";
import { HttpStatusCode } from "axios";
export const sendOtt = async (email: string) => {
return HTTPService.post(await apiURL("/users/ott"), {
email,
client: appName == "auth" ? "totp" : "web",
});
};
export const verifyOtt = async (
email: string,
ott: string,
referral: string,
) => {
const cleanedReferral = `web:${referral?.trim() || ""}`;
return HTTPService.post(await apiURL("/users/verify-email"), {
email,
ott,
source: cleanedReferral,
});
};
export const putAttributes = async (
token: string,
keyAttributes: KeyAttributes,
) =>
HTTPService.put(
await apiURL("/users/attributes"),
{ keyAttributes },
undefined,
{
"X-Auth-Token": token,
},
);
export const logout = async () => {
try {
const token = getToken();
await HTTPService.post(await apiURL("/users/logout"), null, undefined, {
"X-Auth-Token": token,
});
} catch (e) {
// ignore if token missing can be triggered during sign up.
if (e instanceof Error && e.message === CustomError.TOKEN_MISSING) {
return;
}
// ignore if unauthorized, can be triggered during on token expiry.
else if (
e instanceof ApiError &&
e.httpStatusCode === HttpStatusCode.Unauthorized
) {
return;
}
throw e;
}
};
export const verifyTwoFactor = async (code: string, sessionID: string) => {
const resp = await HTTPService.post(
await apiURL("/users/two-factor/verify"),
{
code,
sessionID,
},
);
return resp.data as UserVerificationResponse;
};
/** The type of the second factor we're trying to act on */
export type TwoFactorType = "totp" | "passkey";
export const recoverTwoFactor = async (
sessionID: string,
twoFactorType: TwoFactorType,
) => {
const resp = await HTTPService.get(
await apiURL("/users/two-factor/recover"),
{
sessionID,
twoFactorType,
},
);
return resp.data as TwoFactorRecoveryResponse;
};
export const removeTwoFactor = async (
sessionID: string,
secret: string,
twoFactorType: TwoFactorType,
) => {
const resp = await HTTPService.post(
await apiURL("/users/two-factor/remove"),
{
sessionID,
secret,
twoFactorType,
},
);
return resp.data as TwoFactorVerificationResponse;
};
export const changeEmail = async (email: string, ott: string) => {
await HTTPService.post(
await apiURL("/users/change-email"),
{
email,
ott,
},
undefined,
{
"X-Auth-Token": getToken(),
},
);
};
export const sendOTTForEmailChange = async (email: string) => {
await HTTPService.post(await apiURL("/users/ott"), {
email,
client: "web",
purpose: "change",
});
};
export const setupTwoFactor = async () => {
const resp = await HTTPService.post(
await apiURL("/users/two-factor/setup"),
null,
undefined,
{
"X-Auth-Token": getToken(),
},
);
return resp.data as TwoFactorSecret;
};
export const enableTwoFactor = async (
code: string,
recoveryEncryptedTwoFactorSecret: B64EncryptionResult,
) => {
await HTTPService.post(
await apiURL("/users/two-factor/enable"),
{
code,
encryptedTwoFactorSecret:
recoveryEncryptedTwoFactorSecret.encryptedData,
twoFactorSecretDecryptionNonce:
recoveryEncryptedTwoFactorSecret.nonce,
},
undefined,
{
"X-Auth-Token": getToken(),
},
);
};
export const setRecoveryKey = async (token: string, recoveryKey: RecoveryKey) =>
HTTPService.put(
await apiURL("/users/recovery-key"),
recoveryKey,
undefined,
{
"X-Auth-Token": token,
},
);
export const disableTwoFactor = async () => {
await HTTPService.post(
await apiURL("/users/two-factor/disable"),
null,
undefined,
{
"X-Auth-Token": getToken(),
},
);
};