fix: switch js-cookies to cookies-next for a more reliable client/server value

This commit is contained in:
Nicolas Meienberger 2023-06-10 11:35:04 +02:00
parent 1fce007e3f
commit 8a86cfd072
6 changed files with 30 additions and 24 deletions

View file

@ -50,12 +50,12 @@
"argon2": "^0.30.3",
"clsx": "^1.1.1",
"connect-redis": "^7.1.0",
"cookies-next": "^2.1.1",
"drizzle-orm": "^0.26.0",
"express": "^4.17.3",
"express-session": "^1.17.3",
"fs-extra": "^11.1.1",
"isomorphic-fetch": "^3.0.0",
"js-cookie": "^3.0.5",
"lodash.merge": "^4.6.2",
"next": "13.4.4",
"next-intl": "^2.14.2",

24
pnpm-lock.yaml generated
View file

@ -64,6 +64,9 @@ dependencies:
connect-redis:
specifier: ^7.1.0
version: 7.1.0(express-session@1.17.3)
cookies-next:
specifier: ^2.1.1
version: 2.1.1
drizzle-orm:
specifier: ^0.26.0
version: 0.26.0(@types/pg@8.6.6)(pg@8.11.0)
@ -79,9 +82,6 @@ dependencies:
isomorphic-fetch:
specifier: ^3.0.0
version: 3.0.0
js-cookie:
specifier: ^3.0.5
version: 3.0.5
lodash.merge:
specifier: ^4.6.2
version: 4.6.2
@ -2886,7 +2886,6 @@ packages:
/@types/cookie@0.4.1:
resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==}
dev: true
/@types/cookiejar@2.1.2:
resolution: {integrity: sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==}
@ -3023,6 +3022,10 @@ packages:
resolution: {integrity: sha512-9PuLtBboc/+JJ7FshmJWv769gDonTpItN0Ol5TMwclpSQNjVyB2SRxSKBcTtbSysSL5R7Oea06kTTFNciCoYwA==}
dev: true
/@types/node@16.18.35:
resolution: {integrity: sha512-yqU2Rf94HFZqgHf6Tuyc/IqVD0l3U91KjvypSr1GtJKyrnl6L/kfnxVqN4QOwcF5Zx9tO/HKK+fozGr5AtqA+g==}
dev: false
/@types/node@20.2.5:
resolution: {integrity: sha512-JJulVEQXmiY9Px5axXHeYGLSjhkZEnD+MDPDGbCbIAbMslkKwmygtZFy1X6s/075Yo94sf8GuSlFfPzysQrWZQ==}
@ -4113,6 +4116,14 @@ packages:
resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==}
dev: true
/cookies-next@2.1.1:
resolution: {integrity: sha512-AZGZPdL1hU3jCjN2UMJTGhLOYzNUN9Gm+v8BdptYIHUdwz397Et1p+sZRfvAl8pKnnmMdX2Pk9xDRKCGBum6GA==}
dependencies:
'@types/cookie': 0.4.1
'@types/node': 16.18.35
cookie: 0.4.2
dev: false
/copy-anything@3.0.3:
resolution: {integrity: sha512-fpW2W/BqEzqPp29QS+MwwfisHCQZtiduTe/m8idFo0xbti9fIZ2WVhAsCv4ggFVH3AgCkVdpoOCtQC6gBrdhjw==}
engines: {node: '>=12.13'}
@ -6891,11 +6902,6 @@ packages:
- ts-node
dev: true
/js-cookie@3.0.5:
resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==}
engines: {node: '>=14'}
dev: false
/js-levenshtein@1.1.6:
resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==}
engines: {node: '>=0.10.0'}

View file

@ -52,7 +52,7 @@ export const Header: React.FC<IProps> = ({ isUpdateAvailable }) => {
</h1>
</Link>
<div className="navbar-nav flex-row order-md-last">
<div className="nav-item d-none d-lg-flex me-3">
<div className="nav-item d-none d-xl-flex me-3">
<div className="btn-list">
<a href="https://github.com/meienberger/runtipi" target="_blank" rel="noreferrer" className="btn btn-dark">
<IconBrandGithub data-testid="icon-github" className="me-1 icon" size={24} />

View file

@ -1,11 +1,11 @@
import { getTRPCMock } from '@/client/mocks/getTrpcMock';
import { server } from '@/client/mocks/server';
import Cookies from 'js-cookie';
import { deleteCookie, setCookie, getCookie } from 'cookies-next';
import { renderHook, waitFor } from '../../../../tests/test-utils';
import { useLocale } from '../useLocale';
beforeEach(() => {
Cookies.remove('locale');
deleteCookie('tipi-locale');
});
describe('test: useLocale()', () => {
@ -28,7 +28,7 @@ describe('test: useLocale()', () => {
it('should return cookie locale if not logged in', async () => {
// arrange
const locale = 'fr-FR';
Cookies.set('locale', locale);
setCookie('tipi-locale', locale);
server.use(getTRPCMock({ path: ['auth', 'me'], response: null }));
// act
@ -82,7 +82,7 @@ describe('test: useLocale()', () => {
// assert
await waitFor(() => {
expect(Cookies.get('locale')).toEqual('fr-FR');
expect(getCookie('tipi-locale')).toEqual('fr-FR');
});
});
@ -102,7 +102,7 @@ describe('test: useLocale()', () => {
// assert
await waitFor(() => {
expect(Cookies.get('locale')).toEqual(locale);
expect(getCookie('tipi-locale')).toEqual(locale);
});
});
});

View file

@ -1,5 +1,5 @@
import { setCookie, getCookie } from 'cookies-next';
import { useRouter } from 'next/router';
import Cookies from 'js-cookie';
import { trpc } from '@/utils/trpc';
import { Locale, getLocaleFromString } from '@/shared/internationalization/locales';
@ -8,9 +8,9 @@ export const useLocale = () => {
const me = trpc.auth.me.useQuery();
const changeUserLocale = trpc.auth.changeLocale.useMutation();
const browserLocale = typeof window !== 'undefined' ? window.navigator.language : undefined;
const cookieLocale = Cookies.get('locale');
const cookieLocale = getCookie('tipi-locale');
const locale = me.data?.locale || cookieLocale || browserLocale || 'en';
const locale = String(me.data?.locale || cookieLocale || browserLocale || 'en');
const ctx = trpc.useContext();
const changeLocale = async (l: Locale) => {
@ -19,9 +19,8 @@ export const useLocale = () => {
await ctx.invalidate();
}
Cookies.set('locale', l, {
expires: 30,
path: '/',
setCookie('tipi-locale', l, {
expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365),
});
router.reload();

View file

@ -1,6 +1,7 @@
import { GetServerSideProps } from 'next';
import merge from 'lodash.merge';
import { getLocaleFromString } from '@/shared/internationalization/locales';
import { getCookie } from 'cookies-next';
export const getAuthedPageProps: GetServerSideProps = async (ctx) => {
const { userId } = ctx.req.session;
@ -20,11 +21,11 @@ export const getAuthedPageProps: GetServerSideProps = async (ctx) => {
};
export const getMessagesPageProps: GetServerSideProps = async (ctx) => {
const { cookies } = ctx.req;
const { locale: sessionLocale } = ctx.req.session;
const cookieLocale = getCookie('tipi-locale', { req: ctx.req });
const browserLocale = ctx.req.headers['accept-language']?.split(',')[0];
const locale = getLocaleFromString(sessionLocale || cookies?.locale || browserLocale || 'en');
const locale = getLocaleFromString(String(sessionLocale || cookieLocale || browserLocale || 'en'));
const englishMessages = (await import(`../messages/en.json`)).default;
const messages = (await import(`../messages/${locale}.json`)).default;