Compare commits
4 Commits
4b2fb40d6f
...
589f9f1a36
Author | SHA1 | Date | |
---|---|---|---|
589f9f1a36 | |||
8bd291beec | |||
00d7ac15a2 | |||
321cad4ffd |
22
package-lock.json
generated
22
package-lock.json
generated
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "test",
|
"name": "fin-check-front",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "test",
|
"name": "fin-check-front",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "^3.0.0",
|
"@sveltejs/adapter-auto": "^3.0.0",
|
||||||
|
@ -13,6 +13,7 @@
|
||||||
"@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",
|
||||||
|
@ -947,6 +948,16 @@
|
||||||
"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",
|
||||||
|
@ -2844,6 +2855,13 @@
|
||||||
"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",
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
"@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",
|
||||||
|
|
|
@ -1,5 +1,61 @@
|
||||||
// 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';
|
||||||
|
|
||||||
|
@ -18,7 +74,11 @@ interface UserData {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic function for making API requests
|
// Generic function for making API requests
|
||||||
export async function apiFetch<T>(endpoint: string, options: RequestInit = {}): Promise<T> {
|
export async function apiFetch<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)
|
||||||
|
|
||||||
|
@ -34,6 +94,17 @@ export async function apiFetch<T>(endpoint: string, options: RequestInit = {}):
|
||||||
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}`;
|
||||||
|
@ -48,11 +119,11 @@ export async function apiFetch<T>(endpoint: string, options: RequestInit = {}):
|
||||||
}
|
}
|
||||||
|
|
||||||
// Login function with type annotation for the response
|
// Login function with type annotation for the response
|
||||||
export async function login(username: string, password: string): Promise<LoginResponse> {
|
export async function login(username: string, password: string, cookies?: Cookies): 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
|
||||||
|
|
|
@ -16,21 +16,11 @@ 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); // Call the backend login
|
const loginResponse = await login(username, password, cookies);
|
||||||
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 necessary data
|
return json({ id: loginResponse.id, name: loginResponse.name });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return json({ error: error.message }, { status: 401 });
|
return json({ error: error.message }, { status: 401 });
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user