Skip to content

Commit 37ffc2c

Browse files
authored
fix: set cookie's SameSite and Secure (kamranahmedse#5186)
* fix: set cookie's `SameSite` and `Secure` * fix: remove caddy file
1 parent dd3a46e commit 37ffc2c

File tree

10 files changed

+46
-56
lines changed

10 files changed

+46
-56
lines changed

src/components/AuthenticationFlow/EmailLoginForm.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Cookies from 'js-cookie';
22
import type { FormEvent } from 'react';
33
import { useState } from 'react';
44
import { httpPost } from '../../lib/http';
5-
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
5+
import { TOKEN_COOKIE_NAME, setAuthToken } from '../../lib/jwt';
66

77
type EmailLoginFormProps = {
88
isDisabled?: boolean;
@@ -34,11 +34,7 @@ export function EmailLoginForm(props: EmailLoginFormProps) {
3434

3535
// Log the user in and reload the page
3636
if (response?.token) {
37-
Cookies.set(TOKEN_COOKIE_NAME, response.token, {
38-
path: '/',
39-
expires: 30,
40-
domain: import.meta.env.DEV ? 'localhost' : '.roadmap.sh',
41-
});
37+
setAuthToken(response.token);
4238
window.location.reload();
4339

4440
return;

src/components/AuthenticationFlow/GitHubButton.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffect, useState } from 'react';
22
import { GitHubIcon } from '../ReactIcons/GitHubIcon.tsx';
33
import Cookies from 'js-cookie';
4-
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
4+
import { TOKEN_COOKIE_NAME, setAuthToken } from '../../lib/jwt';
55
import { httpGet } from '../../lib/http';
66
import { Spinner } from '../ReactIcons/Spinner.tsx';
77

@@ -70,11 +70,7 @@ export function GitHubButton(props: GitHubButtonProps) {
7070

7171
localStorage.removeItem(GITHUB_REDIRECT_AT);
7272
localStorage.removeItem(GITHUB_LAST_PAGE);
73-
Cookies.set(TOKEN_COOKIE_NAME, response.token, {
74-
path: '/',
75-
expires: 30,
76-
domain: import.meta.env.DEV ? 'localhost' : '.roadmap.sh',
77-
});
73+
setAuthToken(response.token);
7874
window.location.href = redirectUrl;
7975
})
8076
.catch((err) => {

src/components/AuthenticationFlow/GoogleButton.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useEffect, useState } from 'react';
22
import Cookies from 'js-cookie';
3-
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
3+
import { TOKEN_COOKIE_NAME, setAuthToken } from '../../lib/jwt';
44
import { httpGet } from '../../lib/http';
55
import { Spinner } from '../ReactIcons/Spinner.tsx';
66
import { GoogleIcon } from '../ReactIcons/GoogleIcon.tsx';
@@ -69,11 +69,7 @@ export function GoogleButton(props: GoogleButtonProps) {
6969

7070
localStorage.removeItem(GOOGLE_REDIRECT_AT);
7171
localStorage.removeItem(GOOGLE_LAST_PAGE);
72-
Cookies.set(TOKEN_COOKIE_NAME, response.token, {
73-
path: '/',
74-
expires: 30,
75-
domain: import.meta.env.DEV ? 'localhost' : '.roadmap.sh',
76-
});
72+
setAuthToken(response.token);
7773
window.location.href = redirectUrl;
7874
})
7975
.catch((err) => {

src/components/AuthenticationFlow/LinkedInButton.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useEffect, useState } from 'react';
22
import Cookies from 'js-cookie';
3-
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
3+
import { TOKEN_COOKIE_NAME, setAuthToken } from '../../lib/jwt';
44
import { httpGet } from '../../lib/http';
55
import { Spinner } from '../ReactIcons/Spinner.tsx';
66
import { LinkedInIcon } from '../ReactIcons/LinkedInIcon.tsx';
@@ -69,11 +69,7 @@ export function LinkedInButton(props: LinkedInButtonProps) {
6969

7070
localStorage.removeItem(LINKEDIN_REDIRECT_AT);
7171
localStorage.removeItem(LINKEDIN_LAST_PAGE);
72-
Cookies.set(TOKEN_COOKIE_NAME, response.token, {
73-
path: '/',
74-
expires: 30,
75-
domain: import.meta.env.DEV ? 'localhost' : '.roadmap.sh',
76-
});
72+
setAuthToken(response.token);
7773
window.location.href = redirectUrl;
7874
})
7975
.catch((err) => {

src/components/AuthenticationFlow/ResetPasswordForm.tsx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { type FormEvent, useEffect, useState } from 'react';
22
import { httpPost } from '../../lib/http';
33
import Cookies from 'js-cookie';
4-
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
4+
import { TOKEN_COOKIE_NAME, setAuthToken } from '../../lib/jwt';
55

66
export function ResetPasswordForm() {
77
const [code, setCode] = useState('');
@@ -37,7 +37,7 @@ export function ResetPasswordForm() {
3737
newPassword: password,
3838
confirmPassword: passwordConfirm,
3939
code,
40-
}
40+
},
4141
);
4242

4343
if (error?.message) {
@@ -53,11 +53,7 @@ export function ResetPasswordForm() {
5353
}
5454

5555
const token = response.token;
56-
Cookies.set(TOKEN_COOKIE_NAME, token, {
57-
path: '/',
58-
expires: 30,
59-
domain: import.meta.env.DEV ? 'localhost' : '.roadmap.sh',
60-
});
56+
setAuthToken(response.token);
6157
window.location.href = '/';
6258
};
6359

src/components/AuthenticationFlow/TriggerVerifyAccount.tsx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useEffect, useState } from 'react';
22
import Cookies from 'js-cookie';
33
import { httpPost } from '../../lib/http';
4-
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
4+
import { TOKEN_COOKIE_NAME, setAuthToken } from '../../lib/jwt';
55
import { Spinner } from '../ReactIcons/Spinner';
66
import { ErrorIcon2 } from '../ReactIcons/ErrorIcon2';
77

@@ -26,11 +26,7 @@ export function TriggerVerifyAccount() {
2626
return;
2727
}
2828

29-
Cookies.set(TOKEN_COOKIE_NAME, response.token, {
30-
path: '/',
31-
expires: 30,
32-
domain: import.meta.env.DEV ? 'localhost' : '.roadmap.sh',
33-
});
29+
setAuthToken(response.token);
3430
window.location.href = '/';
3531
})
3632
.catch((err) => {

src/components/Navigation/navigation.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import Cookies from 'js-cookie';
2-
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
2+
import { TOKEN_COOKIE_NAME, removeAuthToken } from '../../lib/jwt';
33

44
export function logout() {
5-
Cookies.remove(TOKEN_COOKIE_NAME, {
6-
path: '/',
7-
domain: import.meta.env.DEV ? 'localhost' : '.roadmap.sh',
8-
});
5+
removeAuthToken();
96

107
// Reloading will automatically redirect the user if required
118
window.location.reload();

src/components/UpdateProfile/UploadProfilePicture.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Cookies from 'js-cookie';
22
import { type ChangeEvent, type FormEvent, useEffect, useRef, useState } from 'react';
3-
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
3+
import { TOKEN_COOKIE_NAME, removeAuthToken } from '../../lib/jwt';
44

55
interface PreviewFile extends File {
66
preview: string;
@@ -128,7 +128,7 @@ export default function UploadProfilePicture(props: UploadProfilePictureProps) {
128128

129129
// Logout user if token is invalid
130130
if (data.status === 401) {
131-
Cookies.remove(TOKEN_COOKIE_NAME);
131+
removeAuthToken();
132132
window.location.reload();
133133
}
134134
};

src/lib/http.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Cookies from 'js-cookie';
22
import fp from '@fingerprintjs/fingerprintjs';
3-
import { TOKEN_COOKIE_NAME } from './jwt';
3+
import { TOKEN_COOKIE_NAME, removeAuthToken } from './jwt';
44

55
type HttpOptionsType = RequestInit | { headers: Record<string, any> };
66

@@ -30,10 +30,10 @@ type ApiReturn<ResponseType, ErrorType> = {
3030
*/
3131
export async function httpCall<
3232
ResponseType = AppResponse,
33-
ErrorType = AppError
33+
ErrorType = AppError,
3434
>(
3535
url: string,
36-
options?: HttpOptionsType
36+
options?: HttpOptionsType,
3737
): Promise<ApiReturn<ResponseType, ErrorType>> {
3838
try {
3939
const fingerprintPromise = await fp.load({ monitoring: false });
@@ -65,7 +65,7 @@ export async function httpCall<
6565

6666
// Logout user if token is invalid
6767
if (data.status === 401) {
68-
Cookies.remove(TOKEN_COOKIE_NAME);
68+
removeAuthToken();
6969
window.location.reload();
7070
return { response: undefined, error: data as ErrorType };
7171
}
@@ -92,11 +92,11 @@ export async function httpCall<
9292

9393
export async function httpPost<
9494
ResponseType = AppResponse,
95-
ErrorType = AppError
95+
ErrorType = AppError,
9696
>(
9797
url: string,
9898
body: Record<string, any>,
99-
options?: HttpOptionsType
99+
options?: HttpOptionsType,
100100
): Promise<ApiReturn<ResponseType, ErrorType>> {
101101
return httpCall<ResponseType, ErrorType>(url, {
102102
...options,
@@ -108,7 +108,7 @@ export async function httpPost<
108108
export async function httpGet<ResponseType = AppResponse, ErrorType = AppError>(
109109
url: string,
110110
queryParams?: Record<string, any>,
111-
options?: HttpOptionsType
111+
options?: HttpOptionsType,
112112
): Promise<ApiReturn<ResponseType, ErrorType>> {
113113
const searchParams = new URLSearchParams(queryParams).toString();
114114
const queryUrl = searchParams ? `${url}?${searchParams}` : url;
@@ -122,11 +122,11 @@ export async function httpGet<ResponseType = AppResponse, ErrorType = AppError>(
122122

123123
export async function httpPatch<
124124
ResponseType = AppResponse,
125-
ErrorType = AppError
125+
ErrorType = AppError,
126126
>(
127127
url: string,
128128
body: Record<string, any>,
129-
options?: HttpOptionsType
129+
options?: HttpOptionsType,
130130
): Promise<ApiReturn<ResponseType, ErrorType>> {
131131
return httpCall<ResponseType, ErrorType>(url, {
132132
...options,
@@ -138,7 +138,7 @@ export async function httpPatch<
138138
export async function httpPut<ResponseType = AppResponse, ErrorType = AppError>(
139139
url: string,
140140
body: Record<string, any>,
141-
options?: HttpOptionsType
141+
options?: HttpOptionsType,
142142
): Promise<ApiReturn<ResponseType, ErrorType>> {
143143
return httpCall<ResponseType, ErrorType>(url, {
144144
...options,
@@ -149,10 +149,10 @@ export async function httpPut<ResponseType = AppResponse, ErrorType = AppError>(
149149

150150
export async function httpDelete<
151151
ResponseType = AppResponse,
152-
ErrorType = AppError
152+
ErrorType = AppError,
153153
>(
154154
url: string,
155-
options?: HttpOptionsType
155+
options?: HttpOptionsType,
156156
): Promise<ApiReturn<ResponseType, ErrorType>> {
157157
return httpCall<ResponseType, ErrorType>(url, {
158158
...options,

src/lib/jwt.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,20 @@ export function getUser() {
3131

3232
return decodeToken(token);
3333
}
34+
35+
export function setAuthToken(token: string) {
36+
Cookies.set(TOKEN_COOKIE_NAME, token, {
37+
path: '/',
38+
expires: 30,
39+
sameSite: 'lax',
40+
secure: true,
41+
domain: import.meta.env.DEV ? 'localhost' : '.roadmap.sh',
42+
});
43+
}
44+
45+
export function removeAuthToken() {
46+
Cookies.remove(TOKEN_COOKIE_NAME, {
47+
path: '/',
48+
domain: import.meta.env.DEV ? 'localhost' : '.roadmap.sh',
49+
});
50+
}

0 commit comments

Comments
 (0)