mirror of
https://github.com/seanmorley15/AdventureLog.git
synced 2025-07-23 06:49:37 +02:00
feat: Update session cookie domain handling using publicsuffix2 and psl libraries
This commit is contained in:
parent
6a5bfbda2d
commit
d326d38329
5 changed files with 44 additions and 16 deletions
|
@ -14,6 +14,7 @@ from dotenv import load_dotenv
|
||||||
from os import getenv
|
from os import getenv
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from urllib.parse import urlparse
|
from urllib.parse import urlparse
|
||||||
|
from publicsuffix2 import get_sld
|
||||||
# Load environment variables from .env file
|
# Load environment variables from .env file
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
|
|
||||||
|
@ -132,16 +133,26 @@ SESSION_COOKIE_SAMESITE = None
|
||||||
|
|
||||||
SESSION_COOKIE_SECURE = FRONTEND_URL.startswith('https')
|
SESSION_COOKIE_SECURE = FRONTEND_URL.startswith('https')
|
||||||
|
|
||||||
|
# Parse the FRONTEND_URL
|
||||||
parsed_url = urlparse(FRONTEND_URL)
|
parsed_url = urlparse(FRONTEND_URL)
|
||||||
hostname = parsed_url.hostname
|
hostname = parsed_url.hostname
|
||||||
|
|
||||||
|
# Check if the hostname is an IP address
|
||||||
is_ip_address = hostname.replace('.', '').isdigit()
|
is_ip_address = hostname.replace('.', '').isdigit()
|
||||||
|
|
||||||
if is_ip_address:
|
if is_ip_address:
|
||||||
# Do not set a domain for IP addresses
|
# Do not set a domain for IP addresses
|
||||||
SESSION_COOKIE_DOMAIN = None
|
SESSION_COOKIE_DOMAIN = None
|
||||||
else:
|
else:
|
||||||
# Calculate the cookie domain for valid domain names
|
# Use publicsuffix2 to calculate the correct cookie domain
|
||||||
domain_parts = hostname.split('.')
|
cookie_domain = get_sld(hostname)
|
||||||
SESSION_COOKIE_DOMAIN = '.' + '.'.join(domain_parts[-2:]) if len(domain_parts) > 1 else hostname
|
if cookie_domain:
|
||||||
|
SESSION_COOKIE_DOMAIN = f".{cookie_domain}"
|
||||||
|
else:
|
||||||
|
# Fallback to the hostname if parsing fails
|
||||||
|
SESSION_COOKIE_DOMAIN = hostname
|
||||||
|
|
||||||
|
print("SESSION_COOKIE_DOMAIN:", SESSION_COOKIE_DOMAIN)
|
||||||
|
|
||||||
|
|
||||||
# Static files (CSS, JavaScript, Images)
|
# Static files (CSS, JavaScript, Images)
|
||||||
|
|
|
@ -20,4 +20,5 @@ django-ical==1.9.2
|
||||||
icalendar==6.1.0
|
icalendar==6.1.0
|
||||||
ijson==3.3.0
|
ijson==3.3.0
|
||||||
tqdm==4.67.1
|
tqdm==4.67.1
|
||||||
overpy==0.7
|
overpy==0.7
|
||||||
|
publicsuffix2==2.20191221
|
|
@ -44,6 +44,7 @@
|
||||||
"emoji-picker-element": "^1.26.0",
|
"emoji-picker-element": "^1.26.0",
|
||||||
"gsap": "^3.12.7",
|
"gsap": "^3.12.7",
|
||||||
"marked": "^15.0.4",
|
"marked": "^15.0.4",
|
||||||
|
"psl": "^1.15.0",
|
||||||
"qrcode": "^1.5.4",
|
"qrcode": "^1.5.4",
|
||||||
"svelte-i18n": "^4.0.1",
|
"svelte-i18n": "^4.0.1",
|
||||||
"svelte-maplibre": "^0.9.8",
|
"svelte-maplibre": "^0.9.8",
|
||||||
|
|
16
frontend/pnpm-lock.yaml
generated
16
frontend/pnpm-lock.yaml
generated
|
@ -23,6 +23,9 @@ importers:
|
||||||
marked:
|
marked:
|
||||||
specifier: ^15.0.4
|
specifier: ^15.0.4
|
||||||
version: 15.0.4
|
version: 15.0.4
|
||||||
|
psl:
|
||||||
|
specifier: ^1.15.0
|
||||||
|
version: 1.15.0
|
||||||
qrcode:
|
qrcode:
|
||||||
specifier: ^1.5.4
|
specifier: ^1.5.4
|
||||||
version: 1.5.4
|
version: 1.5.4
|
||||||
|
@ -1913,6 +1916,13 @@ packages:
|
||||||
protocol-buffers-schema@3.6.0:
|
protocol-buffers-schema@3.6.0:
|
||||||
resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==}
|
resolution: {integrity: sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==}
|
||||||
|
|
||||||
|
psl@1.15.0:
|
||||||
|
resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==}
|
||||||
|
|
||||||
|
punycode@2.3.1:
|
||||||
|
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
|
||||||
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
qrcode@1.5.4:
|
qrcode@1.5.4:
|
||||||
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
|
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
|
@ -4154,6 +4164,12 @@ snapshots:
|
||||||
|
|
||||||
protocol-buffers-schema@3.6.0: {}
|
protocol-buffers-schema@3.6.0: {}
|
||||||
|
|
||||||
|
psl@1.15.0:
|
||||||
|
dependencies:
|
||||||
|
punycode: 2.3.1
|
||||||
|
|
||||||
|
punycode@2.3.1: {}
|
||||||
|
|
||||||
qrcode@1.5.4:
|
qrcode@1.5.4:
|
||||||
dependencies:
|
dependencies:
|
||||||
dijkstrajs: 1.0.3
|
dijkstrajs: 1.0.3
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { fail, redirect, type RequestEvent } from '@sveltejs/kit';
|
import { fail, redirect, type RequestEvent } from '@sveltejs/kit';
|
||||||
|
// @ts-ignore
|
||||||
|
import psl from 'psl';
|
||||||
import type { Actions, PageServerLoad, RouteParams } from './$types';
|
import type { Actions, PageServerLoad, RouteParams } from './$types';
|
||||||
import { getRandomBackground, getRandomQuote } from '$lib';
|
import { getRandomBackground, getRandomQuote } from '$lib';
|
||||||
import { fetchCSRFToken } from '$lib/index.server';
|
import { fetchCSRFToken } from '$lib/index.server';
|
||||||
|
@ -105,7 +106,7 @@ export const actions: Actions = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
function handleSuccessfulLogin(event: RequestEvent, response: Response) {
|
function handleSuccessfulLogin(event: RequestEvent<RouteParams, '/login'>, response: Response) {
|
||||||
const setCookieHeader = response.headers.get('Set-Cookie');
|
const setCookieHeader = response.headers.get('Set-Cookie');
|
||||||
if (setCookieHeader) {
|
if (setCookieHeader) {
|
||||||
const sessionIdRegex = /sessionid=([^;]+).*?expires=([^;]+)/;
|
const sessionIdRegex = /sessionid=([^;]+).*?expires=([^;]+)/;
|
||||||
|
@ -113,24 +114,22 @@ function handleSuccessfulLogin(event: RequestEvent, response: Response) {
|
||||||
if (match) {
|
if (match) {
|
||||||
const [, sessionId, expiryString] = match;
|
const [, sessionId, expiryString] = match;
|
||||||
|
|
||||||
// Get the proper cookie domain
|
// Get the proper cookie domain using psl
|
||||||
const hostname = event.url.hostname;
|
const hostname = event.url.hostname;
|
||||||
const domainParts = hostname.split('.');
|
let cookieDomain;
|
||||||
let cookieDomain: string | undefined = undefined;
|
|
||||||
|
|
||||||
// Check if hostname is an IP address
|
// Check if hostname is an IP address
|
||||||
const isIPAddress = /^\d{1,3}(\.\d{1,3}){3}$/.test(hostname);
|
const isIPAddress = /^\d{1,3}(\.\d{1,3}){3}$/.test(hostname);
|
||||||
|
|
||||||
if (!isIPAddress) {
|
if (!isIPAddress) {
|
||||||
if (domainParts.length > 2) {
|
const parsed = psl.parse(hostname);
|
||||||
// For subdomains like app.mydomain.com -> .mydomain.com
|
|
||||||
cookieDomain = '.' + domainParts.slice(-2).join('.');
|
if (parsed && parsed.domain) {
|
||||||
} else if (domainParts.length === 2) {
|
// Use the parsed domain (e.g., mydomain.com)
|
||||||
// For root domains like mydomain.com -> .mydomain.com
|
cookieDomain = `.${parsed.domain}`;
|
||||||
cookieDomain = '.' + hostname;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Do not set a domain for IP addresses or single-part hostnames
|
// Do not set a domain for IP addresses or invalid hostnames
|
||||||
|
|
||||||
console.log('Setting sessionid cookie with domain:', cookieDomain);
|
console.log('Setting sessionid cookie with domain:', cookieDomain);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue