[FEAT]: add accesstoken interceptor
This commit is contained in:
parent
0fc508c56b
commit
c30186778d
@ -2,6 +2,7 @@ VITE_API_ORIGIN = https://admin.dev.dipal.ru/api/v1
|
|||||||
VITE_API_AUTH_ORIGIN = https://auth.dev.dipal.ru/api/v1/auth
|
VITE_API_AUTH_ORIGIN = https://auth.dev.dipal.ru/api/v1/auth
|
||||||
VITE_API_AUTH_PHONENUMBER = /start-challenge
|
VITE_API_AUTH_PHONENUMBER = /start-challenge
|
||||||
VITE_API_AUTH_LOGIN = /login
|
VITE_API_AUTH_LOGIN = /login
|
||||||
|
VITE_API_AUTH_REFRESH = /refresh-token
|
||||||
VITE_API_PLACES = /place
|
VITE_API_PLACES = /place
|
||||||
VITE_API_USERS = /profile
|
VITE_API_USERS = /profile
|
||||||
VITE_API_USERS_ACCOUNT = /account
|
VITE_API_USERS_ACCOUNT = /account
|
||||||
|
@ -4,9 +4,21 @@ import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
|||||||
import { IOtpAuthDrivenPort } from '~/business-logic/generic/admin-user/authentication/otp-auth/port';
|
import { IOtpAuthDrivenPort } from '~/business-logic/generic/admin-user/authentication/otp-auth/port';
|
||||||
import { OtpAuthResponse } from '~/business-logic/generic/admin-user/authentication/otp-auth/data/reponse-object/otpAuthRO';
|
import { OtpAuthResponse } from '~/business-logic/generic/admin-user/authentication/otp-auth/data/reponse-object/otpAuthRO';
|
||||||
import { OtpAuthDTOReturnType } from '~/business-logic/generic/admin-user/authentication/otp-auth/data/dto/otpAuthDto';
|
import { OtpAuthDTOReturnType } from '~/business-logic/generic/admin-user/authentication/otp-auth/data/dto/otpAuthDto';
|
||||||
|
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
|
||||||
|
|
||||||
const authAdminLogin = (): IOtpAuthDrivenPort => {
|
const authAdminLogin = (
|
||||||
const httpProvider = new HTTPPovider();
|
userAdmin: AdminUserModel | null,
|
||||||
|
updateAccessToken: (newAccessToken: string) => void,
|
||||||
|
navigateToAuth: () => void,
|
||||||
|
): IOtpAuthDrivenPort => {
|
||||||
|
const httpProvider = new HTTPPovider(
|
||||||
|
{
|
||||||
|
accessToken: userAdmin && userAdmin.adminUserData.accessToken && null,
|
||||||
|
refreshToken: userAdmin && userAdmin.adminUserData.refreshToken && null,
|
||||||
|
},
|
||||||
|
updateAccessToken,
|
||||||
|
navigateToAuth,
|
||||||
|
);
|
||||||
const httpHandler = (data: OtpAuthDTOReturnType): Promise<OtpAuthResponse> => {
|
const httpHandler = (data: OtpAuthDTOReturnType): Promise<OtpAuthResponse> => {
|
||||||
const url = apiUrls.generic.authLogin;
|
const url = apiUrls.generic.authLogin;
|
||||||
const options: HttpOptionsType = {
|
const options: HttpOptionsType = {
|
||||||
|
@ -4,12 +4,24 @@ import { PhonenumberAuthDTOReturnType } from '~/business-logic/generic/admin-use
|
|||||||
import { IPhonenumberAuthPort } from '~/business-logic/generic/admin-user/authentication/phonnumber-auth/port';
|
import { IPhonenumberAuthPort } from '~/business-logic/generic/admin-user/authentication/phonnumber-auth/port';
|
||||||
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
|
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
|
||||||
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
||||||
|
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
|
||||||
|
|
||||||
const authAdminPhoneNumberDriven = (): IPhonenumberAuthPort => {
|
const authAdminPhoneNumberDriven = (
|
||||||
|
userAdmin: AdminUserModel | null,
|
||||||
|
updateAccessToken: (newAccessToken: string) => void,
|
||||||
|
navigateToAuth: () => void,
|
||||||
|
): IPhonenumberAuthPort => {
|
||||||
// make http handler ready for the phone number
|
// make http handler ready for the phone number
|
||||||
const wrongPhoneNumberMessage = staticMessages.global.errors.phonenumber;
|
const wrongPhoneNumberMessage = staticMessages.global.errors.phonenumber;
|
||||||
|
|
||||||
const httpProvider = new HTTPPovider();
|
const httpProvider = new HTTPPovider(
|
||||||
|
{
|
||||||
|
accessToken: userAdmin && userAdmin?.adminUserData.accessToken && null,
|
||||||
|
refreshToken: userAdmin && userAdmin?.adminUserData.refreshToken && null,
|
||||||
|
},
|
||||||
|
updateAccessToken,
|
||||||
|
navigateToAuth,
|
||||||
|
);
|
||||||
const httpHandler = (data: PhonenumberAuthDTOReturnType) => {
|
const httpHandler = (data: PhonenumberAuthDTOReturnType) => {
|
||||||
const url = apiUrls.generic.authPhonenumber;
|
const url = apiUrls.generic.authPhonenumber;
|
||||||
const options: HttpOptionsType = {
|
const options: HttpOptionsType = {
|
||||||
|
@ -1,15 +1,27 @@
|
|||||||
import { INewUserData } from '~/business-logic/core/users/create-user/create-account/data/dto/protocols';
|
import { INewUserData } from '~/business-logic/core/users/create-user/create-account/data/dto/protocols';
|
||||||
import { CreateAcountResponseApi } from '~/business-logic/core/users/create-user/create-account/data/response-object/protocols';
|
import { CreateAcountResponseApi } from '~/business-logic/core/users/create-user/create-account/data/response-object/protocols';
|
||||||
import createUserPort from '~/business-logic/core/users/create-user/ports';
|
import createUserPort from '~/business-logic/core/users/create-user/ports';
|
||||||
|
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
|
||||||
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
||||||
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
|
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
|
||||||
import { apiUrls } from '~/driven/utils/configs/appConfig';
|
import { apiUrls } from '~/driven/utils/configs/appConfig';
|
||||||
|
|
||||||
const createAccountAdapter = (): createUserPort['httpAccountHandler'] => {
|
const createAccountAdapter = (
|
||||||
|
userAdmin: AdminUserModel,
|
||||||
|
updateAccessToken: (newAccessToken: string) => void,
|
||||||
|
navigateToAuth: () => void,
|
||||||
|
): createUserPort['httpAccountHandler'] => {
|
||||||
// make url
|
// make url
|
||||||
const url = apiUrls.core.createUserAccount;
|
const url = apiUrls.core.createUserAccount;
|
||||||
// call http provider
|
// call http provider
|
||||||
const httpProvider = new HTTPPovider();
|
const httpProvider = new HTTPPovider(
|
||||||
|
{
|
||||||
|
accessToken: userAdmin.adminUserData.accessToken,
|
||||||
|
refreshToken: userAdmin.adminUserData.refreshToken,
|
||||||
|
},
|
||||||
|
updateAccessToken,
|
||||||
|
navigateToAuth,
|
||||||
|
);
|
||||||
|
|
||||||
const httpHandler = (newUserData: INewUserData) => {
|
const httpHandler = (newUserData: INewUserData) => {
|
||||||
// api options
|
// api options
|
||||||
|
@ -1,14 +1,26 @@
|
|||||||
import { CreateProfileDtoReturnType } from '~/business-logic/core/users/create-user/create-profile/data/dto/protocols';
|
import { CreateProfileDtoReturnType } from '~/business-logic/core/users/create-user/create-profile/data/dto/protocols';
|
||||||
import createUserPort from '~/business-logic/core/users/create-user/ports';
|
import createUserPort from '~/business-logic/core/users/create-user/ports';
|
||||||
|
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
|
||||||
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
||||||
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
|
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
|
||||||
import { apiUrls } from '~/driven/utils/configs/appConfig';
|
import { apiUrls } from '~/driven/utils/configs/appConfig';
|
||||||
|
|
||||||
const createProfileAdapter = (): createUserPort['httpProfileHandler'] => {
|
const createProfileAdapter = (
|
||||||
|
userAdmin: AdminUserModel,
|
||||||
|
updateAccessToken: (newAccessToken: string) => void,
|
||||||
|
navigateToAuth: () => void,
|
||||||
|
): createUserPort['httpProfileHandler'] => {
|
||||||
// make url
|
// make url
|
||||||
const url = apiUrls.core.createUserProfile;
|
const url = apiUrls.core.createUserProfile;
|
||||||
// call http provider
|
// call http provider
|
||||||
const httpProvider = new HTTPPovider();
|
const httpProvider = new HTTPPovider(
|
||||||
|
{
|
||||||
|
accessToken: userAdmin.adminUserData.accessToken,
|
||||||
|
refreshToken: userAdmin.adminUserData.refreshToken,
|
||||||
|
},
|
||||||
|
updateAccessToken,
|
||||||
|
navigateToAuth,
|
||||||
|
);
|
||||||
|
|
||||||
const httpHandler = (newAccountData: CreateProfileDtoReturnType) => {
|
const httpHandler = (newAccountData: CreateProfileDtoReturnType) => {
|
||||||
// api options
|
// api options
|
||||||
|
@ -3,9 +3,14 @@ import IGetPlacesPort from '~/business-logic/core/places/get-places/port';
|
|||||||
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
||||||
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
|
import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
|
||||||
import { apiUrls } from '~/driven/utils/configs/appConfig';
|
import { apiUrls } from '~/driven/utils/configs/appConfig';
|
||||||
|
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
|
||||||
import { getPlacesAdapterReturnType } from './protocols';
|
import { getPlacesAdapterReturnType } from './protocols';
|
||||||
|
|
||||||
const getPlacesAdapter = (): IGetPlacesPort & getPlacesAdapterReturnType => {
|
const getPlacesAdapter = (
|
||||||
|
userAdmin: AdminUserModel,
|
||||||
|
updateAccessToken: (newAccessToken: string) => void,
|
||||||
|
navigateToAuth: () => void,
|
||||||
|
): IGetPlacesPort & getPlacesAdapterReturnType => {
|
||||||
// url of api
|
// url of api
|
||||||
const url = apiUrls.core.getPlaces;
|
const url = apiUrls.core.getPlaces;
|
||||||
// make the options of request
|
// make the options of request
|
||||||
@ -14,7 +19,14 @@ const getPlacesAdapter = (): IGetPlacesPort & getPlacesAdapterReturnType => {
|
|||||||
method: 'GET',
|
method: 'GET',
|
||||||
};
|
};
|
||||||
// make the httpHandler
|
// make the httpHandler
|
||||||
const httpProvider = new HTTPPovider();
|
const httpProvider = new HTTPPovider(
|
||||||
|
{
|
||||||
|
accessToken: userAdmin.adminUserData.accessToken,
|
||||||
|
refreshToken: userAdmin.adminUserData.refreshToken,
|
||||||
|
},
|
||||||
|
updateAccessToken,
|
||||||
|
navigateToAuth,
|
||||||
|
);
|
||||||
|
|
||||||
const httpHandler = async () => httpProvider.request<GetPlacesResponse>(options);
|
const httpHandler = async () => httpProvider.request<GetPlacesResponse>(options);
|
||||||
|
|
||||||
|
@ -3,9 +3,14 @@ import { HttpOptionsType } from '~/driven/boundaries/http-boundary/protocols';
|
|||||||
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
import { HTTPPovider } from '~/driven/boundaries/http-boundary/httpBoundary';
|
||||||
import { GetUsersResponse } from '~/business-logic/core/users/get-users/data/response-object/protocols';
|
import { GetUsersResponse } from '~/business-logic/core/users/get-users/data/response-object/protocols';
|
||||||
import IGetUsersPort from '~/business-logic/core/users/get-users/ports';
|
import IGetUsersPort from '~/business-logic/core/users/get-users/ports';
|
||||||
|
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
|
||||||
import { getUsersAdapterReturnType } from './protocols';
|
import { getUsersAdapterReturnType } from './protocols';
|
||||||
|
|
||||||
const getUsersAdapter = (): IGetUsersPort & getUsersAdapterReturnType => {
|
const getUsersAdapter = (
|
||||||
|
userAdmin: AdminUserModel,
|
||||||
|
updateAccessToken: (newAccessToken: string) => void,
|
||||||
|
navigateToAuth: () => void,
|
||||||
|
): IGetUsersPort & getUsersAdapterReturnType => {
|
||||||
// url of api
|
// url of api
|
||||||
const url = apiUrls.core.getUsers;
|
const url = apiUrls.core.getUsers;
|
||||||
// make the options of request
|
// make the options of request
|
||||||
@ -14,7 +19,14 @@ const getUsersAdapter = (): IGetUsersPort & getUsersAdapterReturnType => {
|
|||||||
method: 'GET',
|
method: 'GET',
|
||||||
};
|
};
|
||||||
// make the httpHandler
|
// make the httpHandler
|
||||||
const httpProvider = new HTTPPovider();
|
const httpProvider = new HTTPPovider(
|
||||||
|
{
|
||||||
|
accessToken: userAdmin.adminUserData.accessToken,
|
||||||
|
refreshToken: userAdmin.adminUserData.refreshToken,
|
||||||
|
},
|
||||||
|
updateAccessToken,
|
||||||
|
navigateToAuth,
|
||||||
|
);
|
||||||
|
|
||||||
const httpHandler = async () => httpProvider.request<GetUsersResponse>(options);
|
const httpHandler = async () => httpProvider.request<GetUsersResponse>(options);
|
||||||
|
|
||||||
|
@ -1,22 +1,88 @@
|
|||||||
import axios from 'axios';
|
/* eslint-disable consistent-return */
|
||||||
|
/* eslint-disable no-param-reassign */
|
||||||
|
import axios, { AxiosInstance } from 'axios';
|
||||||
import { staticMessages } from '~/driven/utils/constants/staticMessages';
|
import { staticMessages } from '~/driven/utils/constants/staticMessages';
|
||||||
import { ApiGlobalResponseObject } from '~/driven/utils/protocols/serviceProtocols';
|
import { ApiGlobalResponseObject } from '~/driven/utils/protocols/serviceProtocols';
|
||||||
|
import { apiUrls } from '~/driven/utils/configs/appConfig';
|
||||||
import { HttpOptionsType } from './protocols';
|
import { HttpOptionsType } from './protocols';
|
||||||
|
|
||||||
|
interface IUserTokens {
|
||||||
|
accessToken: string | null;
|
||||||
|
refreshToken: string | null;
|
||||||
|
}
|
||||||
export class HTTPPovider {
|
export class HTTPPovider {
|
||||||
|
private userTokens: IUserTokens;
|
||||||
|
|
||||||
|
private updateAccessToken: (newAccessToken: string) => void;
|
||||||
|
|
||||||
|
private navigateToAuth: () => void;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
userTokens: IUserTokens,
|
||||||
|
updateAccessToken: (newAccessToken: string) => void,
|
||||||
|
navigateToAuth: () => void,
|
||||||
|
) {
|
||||||
|
this.userTokens = userTokens;
|
||||||
|
this.updateAccessToken = updateAccessToken;
|
||||||
|
this.navigateToAuth = navigateToAuth;
|
||||||
|
}
|
||||||
|
|
||||||
|
private initalizeAxiosInstance() {
|
||||||
|
const instance = axios.create();
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private handleRequestInterceptor() {
|
||||||
|
const axiosInstance = this.initalizeAxiosInstance();
|
||||||
|
axiosInstance.interceptors.request.use((config) => {
|
||||||
|
config.headers.Authorization = `Bearer ${this.userTokens.accessToken}`;
|
||||||
|
return config;
|
||||||
|
});
|
||||||
|
|
||||||
|
return axiosInstance;
|
||||||
|
}
|
||||||
|
|
||||||
async request<R>(customOptions: HttpOptionsType) {
|
async request<R>(customOptions: HttpOptionsType) {
|
||||||
const options: HttpOptionsType = {
|
const axiosInstance = this.handleRequestInterceptor();
|
||||||
...customOptions,
|
this.responseIncepter(axiosInstance);
|
||||||
headers: {
|
|
||||||
...customOptions.headers,
|
const response = await axiosInstance<ApiGlobalResponseObject<R>>(customOptions);
|
||||||
mode: 'cors',
|
|
||||||
credentials: 'include',
|
|
||||||
Authorization: `Bearer eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICI4NXh0WnA5eThxVDBXVDkwUFpuUkRja3N4LWw0clVyM0tHQW5JSU9DckJNIn0.eyJleHAiOjE2ODQ4MzM5NzcsImlhdCI6MTY4NDc0NzU3NywianRpIjoiYjE5MDEyNGItYzRjNC00NzlkLThkYWItN2VjODc1MjljZWQyIiwiaXNzIjoiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3JlYWxtcy9kaXBhbF9kZXYiLCJhdWQiOiJhY2NvdW50Iiwic3ViIjoiY2RmYzY3YzQtZGJkOC00NGVhLWI0OWEtYjQ3MjZhMzNmOTAxIiwidHlwIjoiQmVhcmVyIiwiYXpwIjoiY29tZm9ydGVjaCIsInNlc3Npb25fc3RhdGUiOiJiYjFmNjc3OC0xMzlhLTRmNzItOWM3Ny01NjAwMWU0NDYzNjQiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsiZGVmYXVsdC1yb2xlcy1tYXN0ZXIiLCJvZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsiY29tZm9ydGVjaCI6eyJyb2xlcyI6WyJ1c2VyIiwib3BlcmF0b3IiXX0sImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoiZW1haWwgcHJvZmlsZSIsInNpZCI6ImJiMWY2Nzc4LTEzOWEtNGY3Mi05Yzc3LTU2MDAxZTQ0NjM2NCIsImVtYWlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoiKzc3Nzc3Nzc3Nzc3In0.qJS5_c9g2AADwusGpquWw7zMvc42tzJ0yUMcM6jI6F2MNH2tFDqMhvG0nEnCwXIxJA54DZL8HHPDoxkhq_xyP2SSRKEU-S7pncpa2acNzOYT68pLxBD6s3W-akQxxJVlr92RtegqaHf2BAZMwdMJl4VreX_avPCrEdPzv2dEMX7a2wxteYgzQJsYtaaVyCO4QADMiNVMWgXE00Hnn5Rxuhpe9Y7Kl9cWCO5JY63gYXGFC9yUBEqEYl6o9d6XKMkuiaLJRE2l4k5ycKuJWUjhvCaL7J_f68vJzNhkiuMqmX5q08SDlgktNHzyKTVXkndKz2EpQemzM6SXPLnohPwjAg`,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
const response = await axios<ApiGlobalResponseObject<R>>(options);
|
|
||||||
if (!response) throw new Error(staticMessages.service.errors[500]);
|
if (!response) throw new Error(staticMessages.service.errors[500]);
|
||||||
|
|
||||||
return response.data.data;
|
return response.data.data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo should be handled in business logic
|
||||||
|
*/
|
||||||
|
private async refreshAccessToken() {
|
||||||
|
try {
|
||||||
|
const response = await axios.post(apiUrls.generic.authRefresh, {
|
||||||
|
refresh_token: this.userTokens.refreshToken,
|
||||||
|
});
|
||||||
|
this.updateAccessToken(response.data.access_token as string);
|
||||||
|
return response.data.access_token;
|
||||||
|
} catch (err) {
|
||||||
|
this.navigateToAuth();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private responseIncepter(axiosInstance: AxiosInstance) {
|
||||||
|
axiosInstance.interceptors.response.use(
|
||||||
|
(response) => response,
|
||||||
|
(error) => {
|
||||||
|
const originalRequest = error.config;
|
||||||
|
|
||||||
|
if (error.response.status === 401 && error.response.message === 'Unauthorized') {
|
||||||
|
const newAccessToken = this.refreshAccessToken().then(() => {
|
||||||
|
originalRequest.headers.Authorization = `Bearer ${newAccessToken}`;
|
||||||
|
return axios(originalRequest);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(error);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,5 +36,6 @@ export const apiUrls = {
|
|||||||
generic: {
|
generic: {
|
||||||
authPhonenumber: `${ENVs.apiAuthOrigin}${ENVs.apiAuthPhonenumber}`,
|
authPhonenumber: `${ENVs.apiAuthOrigin}${ENVs.apiAuthPhonenumber}`,
|
||||||
authLogin: `${ENVs.apiAuthOrigin}${ENVs.apiAuthLogin}`,
|
authLogin: `${ENVs.apiAuthOrigin}${ENVs.apiAuthLogin}`,
|
||||||
|
authRefresh: `${ENVs.apiAuthOrigin}${ENVs.apiAuthRefresh}`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@ export const ENVs = {
|
|||||||
apiAuthOrigin: process.env.VITE_API_AUTH_ORIGIN,
|
apiAuthOrigin: process.env.VITE_API_AUTH_ORIGIN,
|
||||||
apiAuthPhonenumber: process.env.VITE_API_AUTH_PHONENUMBER,
|
apiAuthPhonenumber: process.env.VITE_API_AUTH_PHONENUMBER,
|
||||||
apiAuthLogin: process.env.VITE_API_AUTH_LOGIN,
|
apiAuthLogin: process.env.VITE_API_AUTH_LOGIN,
|
||||||
|
apiAuthRefresh: process.env.VITE_API_AUTH_REFRESH,
|
||||||
apiGetPlaces: process.env.VITE_API_PLACES,
|
apiGetPlaces: process.env.VITE_API_PLACES,
|
||||||
apiGetUsers: process.env.VITE_API_USERS,
|
apiGetUsers: process.env.VITE_API_USERS,
|
||||||
apiCreateUserAccount: process.env.VITE_API_USERS_ACCOUNT,
|
apiCreateUserAccount: process.env.VITE_API_USERS_ACCOUNT,
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
|
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
|
||||||
|
|
||||||
interface IUserContext {
|
export interface IUserContext {
|
||||||
user: AdminUserModel | null;
|
user: AdminUserModel | null;
|
||||||
setUser: React.Dispatch<React.SetStateAction<AdminUserModel | null>> | null;
|
setUser: React.Dispatch<React.SetStateAction<AdminUserModel | null>> | null;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import StateManagementService from '~/driven/boundaries/state-management';
|
import StateManagementService from '~/driven/boundaries/state-management';
|
||||||
|
import StorageService from '~/driven/boundaries/storage-boundary';
|
||||||
|
import { NavigateFunction } from 'react-router-dom';
|
||||||
|
import { appConfig, routes } from '../configs/appConfig';
|
||||||
import { errorHandlingStateTypes, UIErrorHandling } from './protocols/globalHelpersProtocols';
|
import { errorHandlingStateTypes, UIErrorHandling } from './protocols/globalHelpersProtocols';
|
||||||
|
import { IUserContext } from './contexts/userContext';
|
||||||
|
|
||||||
export const UIErrorHandlingFactory = <DATA_RESPONSE>({
|
export const UIErrorHandlingFactory = <DATA_RESPONSE>({
|
||||||
state,
|
state,
|
||||||
@ -26,3 +30,21 @@ export const prepareStateManagementForVM = <ReturnType>(apiUrl: string, model: (
|
|||||||
export const checkPhoneNumberInput = (newValue: string) => {
|
export const checkPhoneNumberInput = (newValue: string) => {
|
||||||
return (Number.isFinite(+newValue) || newValue === '+') && newValue.length <= 12;
|
return (Number.isFinite(+newValue) || newValue === '+') && newValue.length <= 12;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const updateAccessToken = (newAccessToken: string, userContext: IUserContext) => {
|
||||||
|
const { setUser, user } = userContext;
|
||||||
|
if (!user || !setUser) return;
|
||||||
|
const storage = StorageService.localStorage();
|
||||||
|
user.adminUserData.accessToken = newAccessToken;
|
||||||
|
storage.setData(appConfig.adminUserStorageKey, user);
|
||||||
|
setUser(user);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const navigateToAuth = (userCtx: IUserContext, navigate: NavigateFunction) => {
|
||||||
|
const { setUser } = userCtx;
|
||||||
|
const storage = StorageService.localStorage();
|
||||||
|
storage.deleteData(appConfig.adminUserStorageKey);
|
||||||
|
if (!setUser) return;
|
||||||
|
setUser(null);
|
||||||
|
navigate(routes.authentication);
|
||||||
|
};
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { useUser } from '../contexts/userContext';
|
||||||
|
import { navigateToAuth, updateAccessToken } from '../globalHelpers';
|
||||||
|
|
||||||
|
const useGetNavigatorAndTokenUpdater = () => {
|
||||||
|
const userData = useUser();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const notLoginAuth = () => {
|
||||||
|
navigateToAuth(userData, navigate);
|
||||||
|
};
|
||||||
|
|
||||||
|
const accessTokenUpdateHandler = (newAccessToken: string) => {
|
||||||
|
updateAccessToken(newAccessToken, userData);
|
||||||
|
};
|
||||||
|
return {
|
||||||
|
notLoginAuth,
|
||||||
|
accessTokenUpdateHandler,
|
||||||
|
userData,
|
||||||
|
navigate,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useGetNavigatorAndTokenUpdater;
|
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable react/no-array-index-key */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import RowItem from './table-row-item/view/RowItem';
|
import RowItem from './table-row-item/view/RowItem';
|
||||||
import { ITableRowProps } from './protocols';
|
import { ITableRowProps } from './protocols';
|
||||||
@ -6,7 +7,14 @@ export default function TableRowView(props: ITableRowProps) {
|
|||||||
const { isSelected, setSelectedRowId, rowData } = props;
|
const { isSelected, setSelectedRowId, rowData } = props;
|
||||||
const { rowId, rowItemsTitle } = rowData;
|
const { rowId, rowItemsTitle } = rowData;
|
||||||
const columns = rowItemsTitle.map((rowItemTitle, index) => {
|
const columns = rowItemsTitle.map((rowItemTitle, index) => {
|
||||||
return <RowItem key={rowItemTitle} hasCheckbox={index === 0} isSelected={isSelected} title={rowItemTitle} />;
|
return (
|
||||||
|
<RowItem
|
||||||
|
key={(rowItemTitle || 'row') + index}
|
||||||
|
hasCheckbox={index === 0}
|
||||||
|
isSelected={isSelected}
|
||||||
|
title={rowItemTitle}
|
||||||
|
/>
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return <tr onClick={() => setSelectedRowId(rowId)}>{columns}</tr>;
|
return <tr onClick={() => setSelectedRowId(rowId)}>{columns}</tr>;
|
||||||
|
@ -2,14 +2,27 @@ import React from 'react';
|
|||||||
import createAccountAdapter from '~/driven/adapters/create-account-adapter/createAccountAdapter';
|
import createAccountAdapter from '~/driven/adapters/create-account-adapter/createAccountAdapter';
|
||||||
import createProfileAdapter from '~/driven/adapters/create-profile-adapter/createProfileAdapter';
|
import createProfileAdapter from '~/driven/adapters/create-profile-adapter/createProfileAdapter';
|
||||||
import CreateUserInfra from '~/business-logic/core/users/create-user';
|
import CreateUserInfra from '~/business-logic/core/users/create-user';
|
||||||
|
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
|
||||||
|
import useGetNavigatorAndTokenUpdater from '~/driven/utils/helpers/hooks/getNavigatorAndAccessTokenUpdator';
|
||||||
import CreateUserView from '../view/CreateUserView';
|
import CreateUserView from '../view/CreateUserView';
|
||||||
import useCreateUserVM from '../viewmodel/CreateUserVM';
|
import useCreateUserVM from '../viewmodel/CreateUserVM';
|
||||||
import createUserModel from '../model/createUserModel';
|
import createUserModel from '../model/createUserModel';
|
||||||
|
|
||||||
export default function CreateUser() {
|
export default function CreateUser() {
|
||||||
|
const { accessTokenUpdateHandler, notLoginAuth, userData } = useGetNavigatorAndTokenUpdater();
|
||||||
|
|
||||||
|
const { user } = userData;
|
||||||
// get adapters from driven layer
|
// get adapters from driven layer
|
||||||
const createAccountDrivenAdapter = createAccountAdapter();
|
const createAccountDrivenAdapter = createAccountAdapter(
|
||||||
const createProfileDrivenAdapter = createProfileAdapter();
|
user as AdminUserModel,
|
||||||
|
accessTokenUpdateHandler,
|
||||||
|
notLoginAuth,
|
||||||
|
);
|
||||||
|
const createProfileDrivenAdapter = createProfileAdapter(
|
||||||
|
user as AdminUserModel,
|
||||||
|
accessTokenUpdateHandler,
|
||||||
|
notLoginAuth,
|
||||||
|
);
|
||||||
// pass to the logic and get the usecase
|
// pass to the logic and get the usecase
|
||||||
const createUserInfra = new CreateUserInfra(createAccountDrivenAdapter, createProfileDrivenAdapter);
|
const createUserInfra = new CreateUserInfra(createAccountDrivenAdapter, createProfileDrivenAdapter);
|
||||||
const createUserLogic = createUserInfra.execute();
|
const createUserLogic = createUserInfra.execute();
|
||||||
|
@ -3,12 +3,17 @@ import getPlaces from '~/business-logic/core/places/get-places';
|
|||||||
import getPlacesAdapter from '~/driven/adapters/get-places-adapter/getPlacesAdapter';
|
import getPlacesAdapter from '~/driven/adapters/get-places-adapter/getPlacesAdapter';
|
||||||
import PlacesModel from '~/business-logic/core/places/common/model/placesModel';
|
import PlacesModel from '~/business-logic/core/places/common/model/placesModel';
|
||||||
import { prepareStateManagementForVM } from '~/driven/utils/helpers/globalHelpers';
|
import { prepareStateManagementForVM } from '~/driven/utils/helpers/globalHelpers';
|
||||||
|
import useGetNavigatorAndTokenUpdater from '~/driven/utils/helpers/hooks/getNavigatorAndAccessTokenUpdator';
|
||||||
|
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
|
||||||
import PlacesListView from '../view/PlacesListView';
|
import PlacesListView from '../view/PlacesListView';
|
||||||
import usePlacesListVM from '../viewmodel/placesListVM';
|
import usePlacesListVM from '../viewmodel/placesListVM';
|
||||||
import placesListModel from '../model/placesListModel';
|
import placesListModel from '../model/placesListModel';
|
||||||
|
|
||||||
const prepareTheLogicForModel = () => {
|
const prepareTheLogicForModel = () => {
|
||||||
const gettingPlacesDrivenAdapter = getPlacesAdapter();
|
const { accessTokenUpdateHandler, notLoginAuth, userData } = useGetNavigatorAndTokenUpdater();
|
||||||
|
|
||||||
|
const { user } = userData;
|
||||||
|
const gettingPlacesDrivenAdapter = getPlacesAdapter(user as AdminUserModel, accessTokenUpdateHandler, notLoginAuth);
|
||||||
const { url } = gettingPlacesDrivenAdapter;
|
const { url } = gettingPlacesDrivenAdapter;
|
||||||
const getingPlacesLogic = getPlaces(gettingPlacesDrivenAdapter);
|
const getingPlacesLogic = getPlaces(gettingPlacesDrivenAdapter);
|
||||||
return { getingPlacesLogic, url };
|
return { getingPlacesLogic, url };
|
||||||
|
@ -3,19 +3,24 @@ import getUsersAdapter from '~/driven/adapters/get-users-adapter/getUsersAdapter
|
|||||||
import getUsers from '~/business-logic/core/users/get-users';
|
import getUsers from '~/business-logic/core/users/get-users';
|
||||||
import UsersModel from '~/business-logic/core/users/common/data/model/usersModel';
|
import UsersModel from '~/business-logic/core/users/common/data/model/usersModel';
|
||||||
import { prepareStateManagementForVM } from '~/driven/utils/helpers/globalHelpers';
|
import { prepareStateManagementForVM } from '~/driven/utils/helpers/globalHelpers';
|
||||||
|
import useGetNavigatorAndTokenUpdater from '~/driven/utils/helpers/hooks/getNavigatorAndAccessTokenUpdator';
|
||||||
|
import AdminUserModel from '~/business-logic/generic/admin-user/common/data/model/adminUserModel';
|
||||||
import useUsersListVM from '../viewmodel/usersListVM';
|
import useUsersListVM from '../viewmodel/usersListVM';
|
||||||
import UsersListView from '../view/UsersListView';
|
import UsersListView from '../view/UsersListView';
|
||||||
import usersListModel from '../model/usersListModel';
|
import usersListModel from '../model/usersListModel';
|
||||||
|
|
||||||
const prepareTheLogicForModel = () => {
|
const usePrepareTheLogicForModel = () => {
|
||||||
const gettingUsersDrivenAdapter = getUsersAdapter();
|
const { accessTokenUpdateHandler, notLoginAuth, userData } = useGetNavigatorAndTokenUpdater();
|
||||||
|
|
||||||
|
const { user } = userData;
|
||||||
|
const gettingUsersDrivenAdapter = getUsersAdapter(user as AdminUserModel, accessTokenUpdateHandler, notLoginAuth);
|
||||||
const { url } = gettingUsersDrivenAdapter;
|
const { url } = gettingUsersDrivenAdapter;
|
||||||
const getingusersLogic = getUsers(gettingUsersDrivenAdapter);
|
const getingusersLogic = getUsers(gettingUsersDrivenAdapter);
|
||||||
return { getingusersLogic, url };
|
return { getingusersLogic, url };
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function UsersList() {
|
export default function UsersList() {
|
||||||
const { getingusersLogic, url } = prepareTheLogicForModel();
|
const { getingusersLogic, url } = usePrepareTheLogicForModel();
|
||||||
const usersModel = async () => await usersListModel(getingusersLogic);
|
const usersModel = async () => await usersListModel(getingusersLogic);
|
||||||
const useGetusersList = prepareStateManagementForVM<UsersModel>(url, usersModel);
|
const useGetusersList = prepareStateManagementForVM<UsersModel>(url, usersModel);
|
||||||
const { selectedRowId, setSelectedRowId, usersData } = useUsersListVM({
|
const { selectedRowId, setSelectedRowId, usersData } = useUsersListVM({
|
||||||
|
@ -3,13 +3,17 @@ import authAdminPhoneNumberDriven from '~/driven/adapters/auth-admin-phonenumber
|
|||||||
import phonenumberAuthInfra from '~/business-logic/generic/admin-user/authentication/phonnumber-auth';
|
import phonenumberAuthInfra from '~/business-logic/generic/admin-user/authentication/phonnumber-auth';
|
||||||
import authAdminLogin from '~/driven/adapters/auth-admin-login/authAdminLogin';
|
import authAdminLogin from '~/driven/adapters/auth-admin-login/authAdminLogin';
|
||||||
import otpAuthInfra from '~/business-logic/generic/admin-user/authentication/otp-auth';
|
import otpAuthInfra from '~/business-logic/generic/admin-user/authentication/otp-auth';
|
||||||
|
import useGetNavigatorAndTokenUpdater from '~/driven/utils/helpers/hooks/getNavigatorAndAccessTokenUpdator';
|
||||||
import AuthenticationView from '../view/AuthenticationView';
|
import AuthenticationView from '../view/AuthenticationView';
|
||||||
|
|
||||||
export default function Authentication() {
|
export default function Authentication() {
|
||||||
const authPhonenumberDriven = authAdminPhoneNumberDriven();
|
const { accessTokenUpdateHandler, notLoginAuth, userData } = useGetNavigatorAndTokenUpdater();
|
||||||
|
const { user } = userData;
|
||||||
|
|
||||||
|
const authPhonenumberDriven = authAdminPhoneNumberDriven(user, accessTokenUpdateHandler, notLoginAuth);
|
||||||
const authPhoneLogic = phonenumberAuthInfra(authPhonenumberDriven);
|
const authPhoneLogic = phonenumberAuthInfra(authPhonenumberDriven);
|
||||||
|
|
||||||
const authLoginDriven = authAdminLogin();
|
const authLoginDriven = authAdminLogin(user, accessTokenUpdateHandler, notLoginAuth);
|
||||||
const otpAuthLogic = otpAuthInfra(authLoginDriven.httpHandler);
|
const otpAuthLogic = otpAuthInfra(authLoginDriven.httpHandler);
|
||||||
|
|
||||||
return <AuthenticationView authPhone={authPhoneLogic} otpAuth={otpAuthLogic} />;
|
return <AuthenticationView authPhone={authPhoneLogic} otpAuth={otpAuthLogic} />;
|
||||||
|
@ -11,7 +11,7 @@ import Sidebar from '~/driving/application/support/sidebar';
|
|||||||
*/
|
*/
|
||||||
export default function MainPageLayout() {
|
export default function MainPageLayout() {
|
||||||
const { user, setUser } = useUser();
|
const { user, setUser } = useUser();
|
||||||
|
console.log('hi');
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const storage = StorageService.localStorage<AdminUserModel>();
|
const storage = StorageService.localStorage<AdminUserModel>();
|
||||||
const currentUser = storage.getData(appConfig.adminUserStorageKey);
|
const currentUser = storage.getData(appConfig.adminUserStorageKey);
|
||||||
|
@ -5,7 +5,7 @@ import { useUser } from '~/driven/utils/helpers/contexts/userContext';
|
|||||||
|
|
||||||
export default function UserLoginLayout() {
|
export default function UserLoginLayout() {
|
||||||
const { user } = useUser();
|
const { user } = useUser();
|
||||||
|
console.log('hhhh');
|
||||||
if (user) return <Navigate to={routes.usersList} replace />;
|
if (user && user.adminUserData.accessToken) return <Navigate to={routes.usersList} replace />;
|
||||||
return <Outlet />;
|
return <Outlet />;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user