feat: add cookie management and HTTP client for user and admin authentication
This commit is contained in:
parent
0c38a775e3
commit
c1bacacb49
7
app/configs/storages.ts
Normal file
7
app/configs/storages.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export const USER_COOKIES = {
|
||||||
|
token: '__lg-usr-tkn',
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ADMIN_COOKIES = {
|
||||||
|
token: '__lg-adm-tkn',
|
||||||
|
}
|
||||||
13
app/libs/cookie.server.ts
Normal file
13
app/libs/cookie.server.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { createCookie } from 'react-router'
|
||||||
|
|
||||||
|
import { ADMIN_COOKIES, USER_COOKIES } from '~/configs/storages'
|
||||||
|
|
||||||
|
export const userTokenCookie = createCookie(USER_COOKIES.token, {
|
||||||
|
secure: process.env.NODE_ENV === 'production',
|
||||||
|
path: '/news',
|
||||||
|
})
|
||||||
|
|
||||||
|
export const adminTokenCookie = createCookie(ADMIN_COOKIES.token, {
|
||||||
|
secure: process.env.NODE_ENV === 'production',
|
||||||
|
path: '/admin',
|
||||||
|
})
|
||||||
31
app/libs/http-client.ts
Normal file
31
app/libs/http-client.ts
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
import xior, { merge } from 'xior'
|
||||||
|
|
||||||
|
const baseURL = import.meta.env.VITE_API_URL
|
||||||
|
const HttpClient = (token?: string) => {
|
||||||
|
const instance = xior.create({
|
||||||
|
baseURL,
|
||||||
|
})
|
||||||
|
instance.interceptors.request.use((config) => {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.info(`🚀requesting ${config.url}`)
|
||||||
|
|
||||||
|
return merge(config, {
|
||||||
|
headers: {
|
||||||
|
...(token && { Authorization: `Bearer ${token}` }),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
instance.interceptors.response.use(
|
||||||
|
(response) => {
|
||||||
|
return response
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
return Promise.reject(error)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
return instance
|
||||||
|
}
|
||||||
|
|
||||||
|
export default HttpClient
|
||||||
11
app/libs/logout-header.server.ts
Normal file
11
app/libs/logout-header.server.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { USER_COOKIES } from '~/configs/storages'
|
||||||
|
|
||||||
|
export const setUserLogoutHeaders = () => {
|
||||||
|
const responseHeaders = new Headers()
|
||||||
|
responseHeaders.append(
|
||||||
|
'Set-Cookie',
|
||||||
|
`${USER_COOKIES.token}=; Path=/news; Max-Age=0`,
|
||||||
|
)
|
||||||
|
|
||||||
|
return responseHeaders
|
||||||
|
}
|
||||||
@ -8,6 +8,7 @@ import tsEslintParser from '@typescript-eslint/parser'
|
|||||||
import eslintPluginUnicorn from 'eslint-plugin-unicorn'
|
import eslintPluginUnicorn from 'eslint-plugin-unicorn'
|
||||||
import reactPlugin from 'eslint-plugin-react'
|
import reactPlugin from 'eslint-plugin-react'
|
||||||
import pluginQuery from '@tanstack/eslint-plugin-query'
|
import pluginQuery from '@tanstack/eslint-plugin-query'
|
||||||
|
import unusedImports from 'eslint-plugin-unused-imports'
|
||||||
|
|
||||||
export default tseslint.config(
|
export default tseslint.config(
|
||||||
{ ignores: ['dist', 'node_modules', '.react-router'] },
|
{ ignores: ['dist', 'node_modules', '.react-router'] },
|
||||||
@ -28,6 +29,7 @@ export default tseslint.config(
|
|||||||
plugins: {
|
plugins: {
|
||||||
'react-hooks': reactHooks,
|
'react-hooks': reactHooks,
|
||||||
react: reactPlugin,
|
react: reactPlugin,
|
||||||
|
'unused-imports': unusedImports,
|
||||||
},
|
},
|
||||||
languageOptions: {
|
languageOptions: {
|
||||||
parser: tsEslintParser,
|
parser: tsEslintParser,
|
||||||
@ -47,18 +49,7 @@ export default tseslint.config(
|
|||||||
...reactHooks.configs.recommended.rules,
|
...reactHooks.configs.recommended.rules,
|
||||||
...tseslint.configs.recommended.rules,
|
...tseslint.configs.recommended.rules,
|
||||||
...reactPlugin.configs.recommended.rules,
|
...reactPlugin.configs.recommended.rules,
|
||||||
'@typescript-eslint/no-unused-vars': [
|
'@typescript-eslint/no-unused-vars': 'off',
|
||||||
'error',
|
|
||||||
{
|
|
||||||
args: 'all',
|
|
||||||
argsIgnorePattern: '^_',
|
|
||||||
caughtErrors: 'all',
|
|
||||||
caughtErrorsIgnorePattern: '^_',
|
|
||||||
destructuredArrayIgnorePattern: '^_',
|
|
||||||
varsIgnorePattern: '^_',
|
|
||||||
ignoreRestSiblings: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
'unicorn/filename-case': [
|
'unicorn/filename-case': [
|
||||||
'error',
|
'error',
|
||||||
{
|
{
|
||||||
@ -90,7 +81,8 @@ export default tseslint.config(
|
|||||||
'~/layouts/*/*/*/*',
|
'~/layouts/*/*/*/*',
|
||||||
'~/schemas/*/*/*',
|
'~/schemas/*/*/*',
|
||||||
'~/types/*/*',
|
'~/types/*/*',
|
||||||
'~/utils/*/**',
|
'~/utils/*/*',
|
||||||
|
'~/libs/*/*',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -125,6 +117,16 @@ export default tseslint.config(
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
'unused-imports/no-unused-imports': 'error',
|
||||||
|
'unused-imports/no-unused-vars': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
vars: 'all',
|
||||||
|
varsIgnorePattern: '^_',
|
||||||
|
args: 'after-used',
|
||||||
|
argsIgnorePattern: '^_',
|
||||||
|
},
|
||||||
|
],
|
||||||
'react/react-in-jsx-scope': 'off',
|
'react/react-in-jsx-scope': 'off',
|
||||||
'react/jsx-key': [
|
'react/jsx-key': [
|
||||||
'error',
|
'error',
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
"react-hook-form": "^7.54.2",
|
"react-hook-form": "^7.54.2",
|
||||||
"react-router": "^7.1.3",
|
"react-router": "^7.1.3",
|
||||||
"tailwind-merge": "^3.0.1",
|
"tailwind-merge": "^3.0.1",
|
||||||
|
"xior": "^0.6.3",
|
||||||
"zod": "^3.24.2"
|
"zod": "^3.24.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@ -56,6 +57,7 @@
|
|||||||
"eslint-plugin-react": "^7.37.4",
|
"eslint-plugin-react": "^7.37.4",
|
||||||
"eslint-plugin-react-hooks": "^5.1.0",
|
"eslint-plugin-react-hooks": "^5.1.0",
|
||||||
"eslint-plugin-unicorn": "^56.0.1",
|
"eslint-plugin-unicorn": "^56.0.1",
|
||||||
|
"eslint-plugin-unused-imports": "^4.1.4",
|
||||||
"globals": "^15.14.0",
|
"globals": "^15.14.0",
|
||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
"knip": "^5.43.6",
|
"knip": "^5.43.6",
|
||||||
|
|||||||
41
pnpm-lock.yaml
generated
41
pnpm-lock.yaml
generated
@ -65,6 +65,9 @@ importers:
|
|||||||
tailwind-merge:
|
tailwind-merge:
|
||||||
specifier: ^3.0.1
|
specifier: ^3.0.1
|
||||||
version: 3.0.1
|
version: 3.0.1
|
||||||
|
xior:
|
||||||
|
specifier: ^0.6.3
|
||||||
|
version: 0.6.3
|
||||||
zod:
|
zod:
|
||||||
specifier: ^3.24.2
|
specifier: ^3.24.2
|
||||||
version: 3.24.2
|
version: 3.24.2
|
||||||
@ -129,6 +132,9 @@ importers:
|
|||||||
eslint-plugin-unicorn:
|
eslint-plugin-unicorn:
|
||||||
specifier: ^56.0.1
|
specifier: ^56.0.1
|
||||||
version: 56.0.1(eslint@8.57.1)
|
version: 56.0.1(eslint@8.57.1)
|
||||||
|
eslint-plugin-unused-imports:
|
||||||
|
specifier: ^4.1.4
|
||||||
|
version: 4.1.4(@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)
|
||||||
globals:
|
globals:
|
||||||
specifier: ^15.14.0
|
specifier: ^15.14.0
|
||||||
version: 15.14.0
|
version: 15.14.0
|
||||||
@ -2229,6 +2235,15 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
eslint: '>=8.56.0'
|
eslint: '>=8.56.0'
|
||||||
|
|
||||||
|
eslint-plugin-unused-imports@4.1.4:
|
||||||
|
resolution: {integrity: sha512-YptD6IzQjDardkl0POxnnRBhU1OEePMV0nd6siHaRBbd+lyh6NAhFEobiznKU7kTsSsDeSD62Pe7kAM1b7dAZQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@typescript-eslint/eslint-plugin': ^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0
|
||||||
|
eslint: ^9.0.0 || ^8.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@typescript-eslint/eslint-plugin':
|
||||||
|
optional: true
|
||||||
|
|
||||||
eslint-scope@7.2.2:
|
eslint-scope@7.2.2:
|
||||||
resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
|
resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==}
|
||||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||||
@ -3927,6 +3942,10 @@ packages:
|
|||||||
through@2.3.8:
|
through@2.3.8:
|
||||||
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
|
resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==}
|
||||||
|
|
||||||
|
tiny-lru@11.2.11:
|
||||||
|
resolution: {integrity: sha512-27BIW0dIWTYYoWNnqSmoNMKe5WIbkXsc0xaCQHd3/3xT2XMuMJrzHdrO9QBFR14emBz1Bu0dOAs2sCBBrvgPQA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
tinyexec@0.3.2:
|
tinyexec@0.3.2:
|
||||||
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
|
resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==}
|
||||||
|
|
||||||
@ -3944,6 +3963,10 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
typescript: '>=4.8.4'
|
typescript: '>=4.8.4'
|
||||||
|
|
||||||
|
ts-deepmerge@7.0.2:
|
||||||
|
resolution: {integrity: sha512-akcpDTPuez4xzULo5NwuoKwYRtjQJ9eoNfBACiBMaXwNAx7B1PKfe5wqUFJuW5uKzQ68YjDFwPaWHDG1KnFGsA==}
|
||||||
|
engines: {node: '>=14.13.1'}
|
||||||
|
|
||||||
tsconfck@3.1.4:
|
tsconfck@3.1.4:
|
||||||
resolution: {integrity: sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==}
|
resolution: {integrity: sha512-kdqWFGVJqe+KGYvlSO9NIaWn9jT1Ny4oKVzAJsKii5eoE9snzTJzL4+MMVOMn+fikWGFmKEylcXL710V/kIPJQ==}
|
||||||
engines: {node: ^18 || >=20}
|
engines: {node: ^18 || >=20}
|
||||||
@ -4191,6 +4214,9 @@ packages:
|
|||||||
wrappy@1.0.2:
|
wrappy@1.0.2:
|
||||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||||
|
|
||||||
|
xior@0.6.3:
|
||||||
|
resolution: {integrity: sha512-WxDMGk7W2duFoCS0M59Pll/BIGfWiadZp4MMEY0/56K+3Vz400DUTiEZLpuaVcSnv+pCSz05MJz8kohn8wivhg==}
|
||||||
|
|
||||||
xtend@4.0.2:
|
xtend@4.0.2:
|
||||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||||
engines: {node: '>=0.4'}
|
engines: {node: '>=0.4'}
|
||||||
@ -6514,6 +6540,12 @@ snapshots:
|
|||||||
semver: 7.7.0
|
semver: 7.7.0
|
||||||
strip-indent: 3.0.0
|
strip-indent: 3.0.0
|
||||||
|
|
||||||
|
eslint-plugin-unused-imports@4.1.4(@typescript-eslint/eslint-plugin@8.22.0(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1):
|
||||||
|
dependencies:
|
||||||
|
eslint: 8.57.1
|
||||||
|
optionalDependencies:
|
||||||
|
'@typescript-eslint/eslint-plugin': 8.22.0(@typescript-eslint/parser@8.22.0(eslint@8.57.1)(typescript@5.7.3))(eslint@8.57.1)(typescript@5.7.3)
|
||||||
|
|
||||||
eslint-scope@7.2.2:
|
eslint-scope@7.2.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
esrecurse: 4.3.0
|
esrecurse: 4.3.0
|
||||||
@ -8260,6 +8292,8 @@ snapshots:
|
|||||||
|
|
||||||
through@2.3.8: {}
|
through@2.3.8: {}
|
||||||
|
|
||||||
|
tiny-lru@11.2.11: {}
|
||||||
|
|
||||||
tinyexec@0.3.2: {}
|
tinyexec@0.3.2: {}
|
||||||
|
|
||||||
to-regex-range@5.0.1:
|
to-regex-range@5.0.1:
|
||||||
@ -8272,6 +8306,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
typescript: 5.7.3
|
typescript: 5.7.3
|
||||||
|
|
||||||
|
ts-deepmerge@7.0.2: {}
|
||||||
|
|
||||||
tsconfck@3.1.4(typescript@5.7.3):
|
tsconfck@3.1.4(typescript@5.7.3):
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
typescript: 5.7.3
|
typescript: 5.7.3
|
||||||
@ -8528,6 +8564,11 @@ snapshots:
|
|||||||
|
|
||||||
wrappy@1.0.2: {}
|
wrappy@1.0.2: {}
|
||||||
|
|
||||||
|
xior@0.6.3:
|
||||||
|
dependencies:
|
||||||
|
tiny-lru: 11.2.11
|
||||||
|
ts-deepmerge: 7.0.2
|
||||||
|
|
||||||
xtend@4.0.2: {}
|
xtend@4.0.2: {}
|
||||||
|
|
||||||
y18n@5.0.8: {}
|
y18n@5.0.8: {}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user