Compare commits

..

No commits in common. "589f9f1a360f323eb9895c1ec0f8ab4700795ea0" and "4b2fb40d6f37c7b000dd084ba8a4f8aedcaf7b9d" have entirely different histories.

4 changed files with 17 additions and 97 deletions

22
package-lock.json generated
View File

@ -1,11 +1,11 @@
{ {
"name": "fin-check-front", "name": "test",
"version": "0.0.1", "version": "0.0.1",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "fin-check-front", "name": "test",
"version": "0.0.1", "version": "0.0.1",
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-auto": "^3.0.0", "@sveltejs/adapter-auto": "^3.0.0",
@ -13,7 +13,6 @@
"@sveltejs/vite-plugin-svelte": "^4.0.0", "@sveltejs/vite-plugin-svelte": "^4.0.0",
"@tailwindcss/forms": "^0.5.9", "@tailwindcss/forms": "^0.5.9",
"@tailwindcss/typography": "^0.5.15", "@tailwindcss/typography": "^0.5.15",
"@types/node": "^22.9.0",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"svelte": "^5.0.0", "svelte": "^5.0.0",
"svelte-check": "^4.0.0", "svelte-check": "^4.0.0",
@ -948,16 +947,6 @@
"dev": true, "dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/node": {
"version": "22.9.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz",
"integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~6.19.8"
}
},
"node_modules/acorn": { "node_modules/acorn": {
"version": "8.14.0", "version": "8.14.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
@ -2855,13 +2844,6 @@
"node": ">=14.17" "node": ">=14.17"
} }
}, },
"node_modules/undici-types": {
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"dev": true,
"license": "MIT"
},
"node_modules/update-browserslist-db": { "node_modules/update-browserslist-db": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz",

View File

@ -15,7 +15,6 @@
"@sveltejs/vite-plugin-svelte": "^4.0.0", "@sveltejs/vite-plugin-svelte": "^4.0.0",
"@tailwindcss/forms": "^0.5.9", "@tailwindcss/forms": "^0.5.9",
"@tailwindcss/typography": "^0.5.15", "@tailwindcss/typography": "^0.5.15",
"@types/node": "^22.9.0",
"autoprefixer": "^10.4.20", "autoprefixer": "^10.4.20",
"svelte": "^5.0.0", "svelte": "^5.0.0",
"svelte-check": "^4.0.0", "svelte-check": "^4.0.0",

View File

@ -1,61 +1,5 @@
// src/lib/api.ts // src/lib/api.ts
import type { Cookies } from "@sveltejs/kit";
// Cookie Helpers {{{
//
interface CookieOptions {
httpOnly: boolean;
secure: boolean;
sameSite: 'strict' | 'lax' | 'none';
maxAge: number;
path: string;
domain?: string;
}
// Helper function to parse set-cookie header
function parseSetCookieHeader(setCookieHeader: string) {
const [cookie, ...attributes] = setCookieHeader.split(';').map(part => part.trim());
const [name, value] = cookie.split('=');
const options: CookieOptions = {
httpOnly: false,
secure: process.env.NODE_ENV === 'production',
sameSite: 'strict',
path: '/',
maxAge: 0,
};
attributes.forEach(attr => {
const [key, val] = attr.split('=');
switch (key.toLowerCase()) {
case 'httponly':
options.httpOnly = true;
break;
case 'secure':
options.secure = true;
break;
case 'samesite':
options.sameSite = val?.toLowerCase() as 'strict' | 'lax' | 'none';
break;
case 'max-age':
options.maxAge = parseInt(val, 10);
break;
case 'path':
options.path = val || '/';
break;
case 'domain':
options.domain = val;
break;
}
});
return { name, value, options };
}
// }}}
//
// Define the base URL of your API // Define the base URL of your API
const BASE_API_URL = import.meta.env.VITE_API_BASE_URL_SERVER || 'http://localhost:3111/api'; const BASE_API_URL = import.meta.env.VITE_API_BASE_URL_SERVER || 'http://localhost:3111/api';
@ -74,11 +18,7 @@ interface UserData {
} }
// Generic function for making API requests // Generic function for making API requests
export async function apiFetch<T>( export async function apiFetch<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
endpoint: string,
options: RequestInit = {},
cookies?: Cookies,
): Promise<T> {
const url = `${BASE_API_URL}${endpoint}`; const url = `${BASE_API_URL}${endpoint}`;
console.log("Fetching ", url) console.log("Fetching ", url)
@ -94,17 +34,6 @@ export async function apiFetch<T>(
try { try {
const response = await fetch(url, config); const response = await fetch(url, config);
console.log(response.headers);
if (response.headers) {
const setCookieHeader = response.headers.get("Set-Cookie");
if (setCookieHeader) {
const parsedCookie = parseSetCookieHeader(setCookieHeader);
if (parsedCookie) {
cookies?.set(parsedCookie.name, parsedCookie.value, parsedCookie.options)
}
}
}
if (!response.ok) { if (!response.ok) {
const errorData = await response.json(); // Parse error response as JSON const errorData = await response.json(); // Parse error response as JSON
const errorMessage = errorData.message || `Error: ${response.status}`; const errorMessage = errorData.message || `Error: ${response.status}`;
@ -119,11 +48,11 @@ export async function apiFetch<T>(
} }
// Login function with type annotation for the response // Login function with type annotation for the response
export async function login(username: string, password: string, cookies?: Cookies): Promise<LoginResponse> { export async function login(username: string, password: string): Promise<LoginResponse> {
return apiFetch<LoginResponse>('/user/login', { return apiFetch<LoginResponse>('/user/login', {
method: 'POST', method: 'POST',
body: JSON.stringify({ username, password }), body: JSON.stringify({ username, password }),
}, cookies); });
} }
// Get user data function with type annotation for the response // Get user data function with type annotation for the response

View File

@ -16,11 +16,21 @@ export async function POST({ request, cookies }) {
console.log("in POST3") console.log("in POST3")
try { try {
console.log("in POST4") console.log("in POST4")
const loginResponse = await login(username, password, cookies); const loginResponse = await login(username, password); // Call the backend login
console.log("loginResponse = ", loginResponse) console.log("loginResponse = ", loginResponse)
const session = loginResponse.headers.get("Set-Cookie");
// Set cookie securely on the server
cookies.set('session', loginResponse.token, {
httpOnly: true, // Prevents JavaScript access
secure: process.env.NODE_ENV === 'production', // Only send over HTTPS in production
sameSite: 'Strict', // Ensures the cookie is only sent in a first-party context
maxAge: 3600 // Expiry time in seconds (e.g., 1 hour)
});
console.log("in POST5") console.log("in POST5")
return json({ id: loginResponse.id, name: loginResponse.name }); return json({ id: loginResponse.id, name: loginResponse.name }); // Return necessary data
} catch (error) { } catch (error) {
return json({ error: error.message }, { status: 401 }); return json({ error: error.message }, { status: 401 });
} }