Files
ColdBreeze-chat-web/src/app/services/auth.ts
T
2023-06-16 17:09:15 +08:00

231 lines
6.4 KiB
TypeScript

import { nanoid } from "@reduxjs/toolkit";
import { createApi } from "@reduxjs/toolkit/query/react";
import {
AuthData,
CredentialResponse,
LoginCredential,
RenewTokenDTO,
RenewTokenResponse
} from "@/types/auth";
import { UserRegDTO, UserRegResponse } from "@/types/user";
import BASE_URL, { KEY_DEVICE_ID, KEY_DEVICE_TOKEN, KEY_LOCAL_MAGIC_TOKEN } from "../config";
import { resetAuthData, setAuthData, updateInitialized, updateToken } from "../slices/auth.data";
import baseQuery from "./base.query";
const getDeviceId = () => {
let d = localStorage.getItem(KEY_DEVICE_ID);
let dt = localStorage.getItem(KEY_DEVICE_TOKEN) || "";
if (!d) {
d = `web:${nanoid()}`;
localStorage.setItem(KEY_DEVICE_ID, d);
}
return { device: d, device_token: dt };
};
export const authApi = createApi({
reducerPath: "authApi",
baseQuery,
endpoints: (builder) => ({
login: builder.mutation<AuthData, LoginCredential>({
query: (credential) => ({
url: "token/login",
method: "POST",
body: {
credential,
device: getDeviceId().device,
device_token: getDeviceId().device_token
}
}),
transformResponse: (data: AuthData) => {
const { avatar_updated_at } = data.user;
return {
...data,
avatar:
avatar_updated_at == 0
? ""
: `${BASE_URL}/resource/avatar?uid=${data.user.uid}&t=${avatar_updated_at}`
};
},
async onQueryStarted(params, { dispatch, queryFulfilled }) {
try {
const { data } = await queryFulfilled;
if (data) {
dispatch(setAuthData(data));
}
// 从localstorage 去掉 magic token
localStorage.removeItem(KEY_LOCAL_MAGIC_TOKEN);
} catch {
console.log("login error");
}
}
}),
guestLogin: builder.query<AuthData, void>({
query: () => ({ url: "/token/login_guest" }),
async onQueryStarted(param, { dispatch, queryFulfilled }) {
try {
const { data } = await queryFulfilled;
if (data) {
dispatch(setAuthData(data));
// 从localstorage 去掉 magic token
localStorage.removeItem(KEY_LOCAL_MAGIC_TOKEN);
}
} catch {
console.log("guest login error");
}
}
}),
register: builder.mutation<UserRegResponse, UserRegDTO>({
query: (data) => ({
url: `/user/register`,
method: "POST",
body: {
...data,
gender: 0,
device: "browser"
}
})
}),
// 更新token
renew: builder.mutation<RenewTokenResponse, RenewTokenDTO>({
query: (data) => ({
url: "/token/renew",
method: "POST",
body: data
}),
async onQueryStarted(params, { dispatch, queryFulfilled }) {
try {
const { data } = await queryFulfilled;
dispatch(updateToken(data));
} catch {
// dispatch(resetAuthData());
console.error("renew token error");
}
}
}),
// 更新 device token
updateDeviceToken: builder.mutation<void, string>({
query: (device_token) => ({
url: "/token/device_token",
method: "PUT",
body: {
device_token
}
})
}),
// 获取openid
getOpenid: builder.mutation<{ url: string }, { issuer: string; redirect_uri: string }>({
query: (data) => ({
url: "/token/openid/authorize",
method: "POST",
body: data
})
}),
checkMagicTokenValid: builder.mutation<boolean, string>({
query: (token) => ({
url: "user/check_magic_token",
method: "POST",
body: { magic_token: token }
})
}),
updatePassword: builder.mutation<void, { old_password: string; new_password: string }>({
query: (data) => ({
url: "user/change_password",
method: "POST",
body: data
})
}),
sendLoginMagicLink: builder.mutation<string, string>({
query: (email) => ({
headers: {
accept: "text/plain"
},
url: `/user/send_login_magic_link?email=${encodeURIComponent(email)}`,
method: "POST",
responseHandler: "text"
})
}),
sendRegMagicLink: builder.mutation<
{
new_magic_token: string;
mail_is_sent: boolean;
},
{
magic_token: string;
email: string;
password: string;
}
>({
query: (data) => ({
url: `/user/send_reg_magic_link`,
method: "POST",
body: data
})
}),
getMetamaskNonce: builder.query<string, string>({
query: (address) => ({
url: `/token/metamask/nonce?public_address=${address}`
})
}),
checkEmail: builder.query<boolean, string>({
query: (email) => ({
url: `/user/check_email?email=${encodeURIComponent(email)}`
})
}),
getCredentials: builder.query<CredentialResponse, void>({
query: () => ({ url: "/token/credentials" })
}),
logout: builder.query<void, void>({
query: () => ({ url: "token/logout" }),
async onQueryStarted(params, { dispatch, queryFulfilled }) {
try {
await queryFulfilled;
dispatch(resetAuthData());
// 重定向到登录
location.href = "/#/login";
} catch {
console.log("logout error");
}
}
}),
getInitialized: builder.query<boolean, void>({
query: () => ({ url: "/admin/system/initialized" }),
async onQueryStarted(params, { dispatch, queryFulfilled }) {
try {
const { data: isInitialized } = await queryFulfilled;
dispatch(updateInitialized(isInitialized));
} catch {
console.log("api initialized error");
}
}
}),
deleteCurrentAccount: builder.query<void, void>({
query: () => ({
url: `/user/delete`,
method: "DELETE"
})
})
})
});
export const {
useLazyGuestLoginQuery,
useGuestLoginQuery,
useLazyCheckEmailQuery,
useGetInitializedQuery,
useSendLoginMagicLinkMutation,
useSendRegMagicLinkMutation,
useGetCredentialsQuery,
useUpdateDeviceTokenMutation,
useGetOpenidMutation,
useRenewMutation,
useLazyGetMetamaskNonceQuery,
useLoginMutation,
useLazyLogoutQuery,
useCheckMagicTokenValidMutation,
useUpdatePasswordMutation,
useRegisterMutation,
useLazyDeleteCurrentAccountQuery
} = authApi;