mirror of
https://github.com/makeplane/plane
synced 2024-06-14 14:31:34 +00:00
chore: updated api service and handled the set password in store
This commit is contained in:
parent
71d0355132
commit
9e60d2c40b
@ -19,7 +19,7 @@ export abstract class APIService {
|
|||||||
(response) => response,
|
(response) => response,
|
||||||
(error) => {
|
(error) => {
|
||||||
if (error.response && error.response.status === 401) window.location.href = "/login";
|
if (error.response && error.response.status === 401) window.location.href = "/login";
|
||||||
return Promise.reject(error.response?.data ?? error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ abstract class APIService {
|
|||||||
(response) => response,
|
(response) => response,
|
||||||
(error) => {
|
(error) => {
|
||||||
if (error.response && error.response.status === 401) window.location.href = "/";
|
if (error.response && error.response.status === 401) window.location.href = "/";
|
||||||
return Promise.reject(error.response?.data ?? error);
|
return Promise.reject(error);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -56,8 +56,8 @@ const SetPasswordPage: NextPageWithLayout = observer(() => {
|
|||||||
const [isPasswordInputFocused, setIsPasswordInputFocused] = useState(false);
|
const [isPasswordInputFocused, setIsPasswordInputFocused] = useState(false);
|
||||||
// hooks
|
// hooks
|
||||||
const { resolvedTheme } = useTheme();
|
const { resolvedTheme } = useTheme();
|
||||||
|
// hooks
|
||||||
const { data: user } = useUser();
|
const { data: user, handleSetPassword } = useUser();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (csrfToken === undefined)
|
if (csrfToken === undefined)
|
||||||
@ -77,15 +77,12 @@ const SetPasswordPage: NextPageWithLayout = observer(() => {
|
|||||||
[passwordFormData]
|
[passwordFormData]
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleSetPassword = async (password: string) => {
|
|
||||||
if (!csrfToken) throw new Error("csrf token not found");
|
|
||||||
await authService.setPassword(csrfToken, { password });
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
|
||||||
try {
|
try {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await handleSetPassword(passwordFormData.password);
|
if (!csrfToken) throw new Error("csrf token not found");
|
||||||
|
await handleSetPassword(csrfToken, { password: passwordFormData.password });
|
||||||
|
router.push("/");
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
setToast({
|
setToast({
|
||||||
type: TOAST_TYPE.ERROR,
|
type: TOAST_TYPE.ERROR,
|
||||||
|
@ -1,107 +1,51 @@
|
|||||||
import axios from "axios";
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import Cookies from "js-cookie";
|
import axios, { AxiosInstance } from "axios";
|
||||||
|
|
||||||
export abstract class APIService {
|
export abstract class APIService {
|
||||||
protected baseURL: string;
|
protected baseURL: string;
|
||||||
protected headers: any = {};
|
private axiosInstance: AxiosInstance;
|
||||||
|
|
||||||
constructor(baseURL: string) {
|
constructor(baseURL: string) {
|
||||||
this.baseURL = baseURL;
|
this.baseURL = baseURL;
|
||||||
}
|
this.axiosInstance = axios.create({
|
||||||
|
baseURL,
|
||||||
setCSRFToken(token: string) {
|
|
||||||
Cookies.set("csrf_token", token, { expires: 30 });
|
|
||||||
}
|
|
||||||
|
|
||||||
getCSRFToken() {
|
|
||||||
return Cookies.get("csrf_token");
|
|
||||||
}
|
|
||||||
|
|
||||||
setRefreshToken(token: string) {
|
|
||||||
Cookies.set("refresh_token", token, { expires: 30 });
|
|
||||||
}
|
|
||||||
|
|
||||||
getRefreshToken() {
|
|
||||||
return Cookies.get("refresh_token");
|
|
||||||
}
|
|
||||||
|
|
||||||
purgeRefreshToken() {
|
|
||||||
Cookies.remove("refresh_token", { path: "/" });
|
|
||||||
}
|
|
||||||
|
|
||||||
setAccessToken(token: string) {
|
|
||||||
Cookies.set("access_token", token, { expires: 30 });
|
|
||||||
}
|
|
||||||
|
|
||||||
getAccessToken() {
|
|
||||||
return Cookies.get("access_token");
|
|
||||||
}
|
|
||||||
|
|
||||||
purgeAccessToken() {
|
|
||||||
Cookies.remove("access_token", { path: "/" });
|
|
||||||
}
|
|
||||||
|
|
||||||
getHeaders() {
|
|
||||||
return {
|
|
||||||
Authorization: `Bearer ${this.getAccessToken()}`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
get(url: string, config = {}): Promise<any> {
|
|
||||||
return axios({
|
|
||||||
method: "get",
|
|
||||||
url: this.baseURL + url,
|
|
||||||
headers: this.getAccessToken() ? this.getHeaders() : {},
|
|
||||||
...config,
|
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.setupInterceptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
post(url: string, data = {}, config = {}): Promise<any> {
|
private setupInterceptors() {
|
||||||
return axios({
|
this.axiosInstance.interceptors.response.use(
|
||||||
method: "post",
|
(response) => response,
|
||||||
url: this.baseURL + url,
|
(error) => {
|
||||||
data,
|
if (error.response && error.response.status === 401) window.location.href = "/accounts/sign-in";
|
||||||
headers: this.getAccessToken() ? this.getHeaders() : {},
|
return Promise.reject(error);
|
||||||
...config,
|
}
|
||||||
withCredentials: true,
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
put(url: string, data = {}, config = {}): Promise<any> {
|
get(url: string, params = {}) {
|
||||||
return axios({
|
return this.axiosInstance.get(url, { params });
|
||||||
method: "put",
|
|
||||||
url: this.baseURL + url,
|
|
||||||
data,
|
|
||||||
headers: this.getAccessToken() ? this.getHeaders() : {},
|
|
||||||
...config,
|
|
||||||
withCredentials: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
patch(url: string, data = {}, config = {}): Promise<any> {
|
post(url: string, data: any, config = {}) {
|
||||||
return axios({
|
return this.axiosInstance.post(url, data, config);
|
||||||
method: "patch",
|
|
||||||
url: this.baseURL + url,
|
|
||||||
data,
|
|
||||||
headers: this.getAccessToken() ? this.getHeaders() : {},
|
|
||||||
...config,
|
|
||||||
withCredentials: true,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(url: string, data?: any, config = {}): Promise<any> {
|
put(url: string, data: any, config = {}) {
|
||||||
return axios({
|
return this.axiosInstance.put(url, data, config);
|
||||||
method: "delete",
|
}
|
||||||
url: this.baseURL + url,
|
|
||||||
data: data,
|
patch(url: string, data: any, config = {}) {
|
||||||
headers: this.getAccessToken() ? this.getHeaders() : {},
|
return this.axiosInstance.patch(url, data, config);
|
||||||
...config,
|
}
|
||||||
withCredentials: true,
|
|
||||||
});
|
delete(url: string, data?: any, config = {}) {
|
||||||
|
return this.axiosInstance.delete(url, { data, ...config });
|
||||||
}
|
}
|
||||||
|
|
||||||
request(config = {}) {
|
request(config = {}) {
|
||||||
return axios(config);
|
return this.axiosInstance(config);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,5 @@
|
|||||||
// types
|
// types
|
||||||
import {
|
import { ICsrfTokenData, IEmailCheckData, IEmailCheckResponse } from "@plane/types";
|
||||||
ICsrfTokenData,
|
|
||||||
IEmailCheckData,
|
|
||||||
IEmailCheckResponse,
|
|
||||||
ILoginTokenResponse,
|
|
||||||
IMagicSignInData,
|
|
||||||
IPasswordSignInData,
|
|
||||||
} from "@plane/types";
|
|
||||||
// helpers
|
// helpers
|
||||||
import { API_BASE_URL } from "@/helpers/common.helper";
|
import { API_BASE_URL } from "@/helpers/common.helper";
|
||||||
// services
|
// services
|
||||||
@ -39,18 +32,6 @@ export class AuthService extends APIService {
|
|||||||
throw error?.response?.data;
|
throw error?.response?.data;
|
||||||
});
|
});
|
||||||
|
|
||||||
async passwordSignIn(data: IPasswordSignInData): Promise<ILoginTokenResponse> {
|
|
||||||
return this.post("/api/sign-in/", data, { headers: {} })
|
|
||||||
.then((response) => {
|
|
||||||
this.setAccessToken(response?.data?.access_token);
|
|
||||||
this.setRefreshToken(response?.data?.refresh_token);
|
|
||||||
return response?.data;
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
throw error?.response?.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async sendResetPasswordLink(data: { email: string }): Promise<any> {
|
async sendResetPasswordLink(data: { email: string }): Promise<any> {
|
||||||
return this.post(`/auth/forgot-password/`, data)
|
return this.post(`/auth/forgot-password/`, data)
|
||||||
.then((response) => response?.data)
|
.then((response) => response?.data)
|
||||||
@ -71,50 +52,6 @@ export class AuthService extends APIService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async resetPassword(
|
|
||||||
uidb64: string,
|
|
||||||
token: string,
|
|
||||||
data: {
|
|
||||||
new_password: string;
|
|
||||||
}
|
|
||||||
): Promise<ILoginTokenResponse> {
|
|
||||||
return this.post(`/api/reset-password/${uidb64}/${token}/`, data, { headers: {} })
|
|
||||||
.then((response) => {
|
|
||||||
if (response?.status === 200) {
|
|
||||||
this.setAccessToken(response?.data?.access_token);
|
|
||||||
this.setRefreshToken(response?.data?.refresh_token);
|
|
||||||
return response?.data;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
throw error?.response?.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async emailSignUp(data: { email: string; password: string }): Promise<ILoginTokenResponse> {
|
|
||||||
return this.post("/api/sign-up/", data, { headers: {} })
|
|
||||||
.then((response) => {
|
|
||||||
this.setAccessToken(response?.data?.access_token);
|
|
||||||
this.setRefreshToken(response?.data?.refresh_token);
|
|
||||||
return response?.data;
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
throw error?.response?.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async socialAuth(data: any): Promise<ILoginTokenResponse> {
|
|
||||||
return this.post("/api/social-auth/", data, { headers: {} })
|
|
||||||
.then((response) => {
|
|
||||||
this.setAccessToken(response?.data?.access_token);
|
|
||||||
this.setRefreshToken(response?.data?.refresh_token);
|
|
||||||
return response?.data;
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
throw error?.response?.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async generateUniqueCode(data: { email: string }): Promise<any> {
|
async generateUniqueCode(data: { email: string }): Promise<any> {
|
||||||
return this.post("/auth/magic-generate/", data, { headers: {} })
|
return this.post("/auth/magic-generate/", data, { headers: {} })
|
||||||
.then((response) => response?.data)
|
.then((response) => response?.data)
|
||||||
@ -123,34 +60,6 @@ export class AuthService extends APIService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async magicSignIn(data: IMagicSignInData): Promise<any> {
|
|
||||||
return await this.post("/api/magic-sign-in/", data, { headers: {} })
|
|
||||||
.then((response) => {
|
|
||||||
if (response?.status === 200) {
|
|
||||||
this.setAccessToken(response?.data?.access_token);
|
|
||||||
this.setRefreshToken(response?.data?.refresh_token);
|
|
||||||
return response?.data;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
throw error?.response?.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async instanceAdminSignIn(data: IPasswordSignInData): Promise<ILoginTokenResponse> {
|
|
||||||
return await this.post("/api/instances/admins/sign-in/", data, { headers: {} })
|
|
||||||
.then((response) => {
|
|
||||||
if (response?.status === 200) {
|
|
||||||
this.setAccessToken(response?.data?.access_token);
|
|
||||||
this.setRefreshToken(response?.data?.refresh_token);
|
|
||||||
return response?.data;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
throw error?.response?.data;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async signOut(baseUrl: string): Promise<any> {
|
async signOut(baseUrl: string): Promise<any> {
|
||||||
await this.requestCSRFToken().then((data) => {
|
await this.requestCSRFToken().then((data) => {
|
||||||
const csrfToken = data?.csrf_token;
|
const csrfToken = data?.csrf_token;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import cloneDeep from "lodash/cloneDeep";
|
||||||
import set from "lodash/set";
|
import set from "lodash/set";
|
||||||
import { action, makeObservable, observable, runInAction } from "mobx";
|
import { action, makeObservable, observable, runInAction } from "mobx";
|
||||||
// types
|
// types
|
||||||
@ -33,6 +34,7 @@ export interface IUserStore {
|
|||||||
// actions
|
// actions
|
||||||
fetchCurrentUser: () => Promise<IUser | undefined>;
|
fetchCurrentUser: () => Promise<IUser | undefined>;
|
||||||
updateCurrentUser: (data: Partial<IUser>) => Promise<IUser | undefined>;
|
updateCurrentUser: (data: Partial<IUser>) => Promise<IUser | undefined>;
|
||||||
|
handleSetPassword: (csrfToken: string, data: { password: string }) => Promise<IUser | undefined>;
|
||||||
deactivateAccount: () => Promise<void>;
|
deactivateAccount: () => Promise<void>;
|
||||||
signOut: () => Promise<void>;
|
signOut: () => Promise<void>;
|
||||||
}
|
}
|
||||||
@ -75,6 +77,7 @@ export class UserStore implements IUserStore {
|
|||||||
// actions
|
// actions
|
||||||
fetchCurrentUser: action,
|
fetchCurrentUser: action,
|
||||||
updateCurrentUser: action,
|
updateCurrentUser: action,
|
||||||
|
handleSetPassword: action,
|
||||||
deactivateAccount: action,
|
deactivateAccount: action,
|
||||||
signOut: action,
|
signOut: action,
|
||||||
});
|
});
|
||||||
@ -153,6 +156,32 @@ export class UserStore implements IUserStore {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description update the user password
|
||||||
|
* @param data
|
||||||
|
* @returns {Promise<IUser>}
|
||||||
|
*/
|
||||||
|
handleSetPassword = async (csrfToken: string, data: { password: string }): Promise<IUser | undefined> => {
|
||||||
|
const currentUserData = cloneDeep(this.data);
|
||||||
|
try {
|
||||||
|
if (currentUserData && currentUserData.is_password_autoset && this.data) {
|
||||||
|
const user = await this.authService.setPassword(csrfToken, { password: data.password });
|
||||||
|
set(this.data, ["is_password_autoset"], false);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
} catch (error) {
|
||||||
|
if (this.data) set(this.data, ["is_password_autoset"], true);
|
||||||
|
runInAction(() => {
|
||||||
|
this.error = {
|
||||||
|
status: "user-update-error",
|
||||||
|
message: "Failed to update current user",
|
||||||
|
};
|
||||||
|
});
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description deactivates the current user
|
* @description deactivates the current user
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
|
Loading…
Reference in New Issue
Block a user