Rework to add endpoint creation and better handling

This commit is contained in:
CnF-Gris 2025-07-01 17:59:23 +00:00
parent 3de4354458
commit 0fbbfec737
48 changed files with 625 additions and 178 deletions

View File

@ -0,0 +1,73 @@
#!/sbin/openrc-run
description="Nginx http and reverse proxy server"
extra_commands="checkconfig"
extra_started_commands="reload reopen upgrade"
cfgfile=${cfgfile:-/etc/nginx/nginx.conf}
pidfile=/run/nginx/nginx.pid
command=${command:-/usr/sbin/nginx}
command_args="-c $cfgfile"
required_files="$cfgfile"
depend() {
need net
use dns logger netmount
}
start_pre() {
checkpath --directory --owner nginx:nginx ${pidfile%/*}
$command $command_args -t -q
}
checkconfig() {
ebegin "Checking $RC_SVCNAME configuration"
start_pre
eend $?
}
reload() {
ebegin "Reloading $RC_SVCNAME configuration"
# start_pre && start-stop-daemon --signal HUP --pidfile $pidfile
nginx -s reload
# call our service
eend $?
}
reopen() {
ebegin "Reopening $RC_SVCNAME log files"
start-stop-daemon --signal USR1 --pidfile $pidfile
eend $?
}
upgrade() {
start_pre || return 1
ebegin "Upgrading $RC_SVCNAME binary"
einfo "Sending USR2 to old binary"
start-stop-daemon --signal USR2 --pidfile $pidfile
einfo "Sleeping 3 seconds before pid-files checking"
sleep 3
if [ ! -f $pidfile.oldbin ]; then
eerror "File with old pid ($pidfile.oldbin) not found"
return 1
fi
if [ ! -f $pidfile ]; then
eerror "New binary failed to start"
return 1
fi
einfo "Sleeping 3 seconds before WINCH"
sleep 3 ; start-stop-daemon --signal 28 --pidfile $pidfile.oldbin
einfo "Sending QUIT to old binary"
start-stop-daemon --signal QUIT --pidfile $pidfile.oldbin
einfo "Upgrade completed"
eend $? "Upgrade failed"
}

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

@ -12,9 +12,6 @@ server {
# endpoint port
listen PORT ssl;
# Uncomment if http2
# http2 on;
# Here put the unencrypted
# endpoint port
location / {

View File

View File

@ -0,0 +1,50 @@
# Example conf
# Example TLS endpoint
server {
# Use this to avoid port scanners to know
# what you are using
more_clear_headers Server;
# Here put the TLS termination
# endpoint port
listen PORT ssl;
http2 on;
# Here put the unencrypted
# endpoint port
location / {
proxy_pass http://localhost:8080;
}
# Put relevant keys here
ssl_certificate /services-keys/Example/cert.pem;
ssl_certificate_key /services-keys/Example/key.pem;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
}
# Example Termination endpoint
server {
# Use this to avoid port scanners to know
# what you are using
more_clear_headers Server;
# Here put the unencrypted
# endpoint port
listen 127.0.0.1:8080;
# Uncomment if http2
# http2 on;
# Here put the original
# service endpoint port
location / {
proxy_pass https://127.0.0.1:PORT;
}
}

View File

View File

@ -34,13 +34,25 @@ http {
'"$http_user_agent" "$http_x_forwarded_for"';
# Includes virtual hosts configs.
include /etc/nginx/http/*.conf;
include /etc/nginx/grpc/*.conf;
# Includes automatic virtual hosts configs.
include /etc/nginx/active/automatic/grpc/*.conf;
include /etc/nginx/active/automatic/http/*.conf;
include /etc/nginx/active/automatic/http2/*.conf;
# Includes manual configs
include /etc/nginx/active/manual/grpc/*.conf;
include /etc/nginx/active/manual/http/*.conf;
include /etc/nginx/active/manual/http2/*.conf;
include /etc/nginx/active/manual/custom/*.conf;
}
stream {
include /etc/nginx/stream*.conf;
# Include automatic stream config
include /etc/nginx/active/automatic/stream/*.conf;
# Include manual configs
include /etc/nginx/active/manual/stream/*.conf;
}

2
src/app.d.ts vendored
View File

@ -1,4 +1,4 @@
import type { AppData } from "$lib/classes/app-sessions";
import type { AppData } from "$lib/classes/appdata";
// See https://svelte.dev/docs/kit/types#app.d.ts
// for information about these interfaces

View File

@ -1,13 +1,27 @@
import { AppData } from "$lib/classes/app-sessions";
import { AppData } from "$lib/classes/appdata";
import { SESSION_COOKIE_NAME } from "$lib/utils/constants";
import { logger } from "$lib/utils/logger";
import { error, redirect, type Handle } from "@sveltejs/kit";
import { sequence } from "@sveltejs/kit/hooks";
const sessionConstructorHandle = (async ({event, resolve}) => {
const sessionConstructorHandle = (async ({ event, resolve }) => {
const data = await AppData.extractAppDataFromCookies(event.cookies)
// Prevents stray cookies from remaining
// in session (e.g. User has been deleted,
// but cookie is still in session)
if (!data) {
event.cookies.delete(
SESSION_COOKIE_NAME,
{
path: "/"
}
)
}
logger.debug(`User: ${data?.user.username}\nToken ${data?.session.sessionToken}`, "Session Handle")
event.locals.session = data
@ -17,12 +31,12 @@ const sessionConstructorHandle = (async ({event, resolve}) => {
}) satisfies Handle
const apiHandle = (async ({event, resolve}) => {
const apiHandle = (async ({ event, resolve }) => {
logger.debug(event.url.pathname, "API Handle")
logger.debug(`Session Data: ${event.locals.session}`, "API Handle")
if(!event.url.pathname.startsWith("/api/program")) {
if (!event.url.pathname.startsWith("/api/program")) {
// next handle
return await resolve(event)
}
@ -38,12 +52,12 @@ const apiHandle = (async ({event, resolve}) => {
}) satisfies Handle
const appHandle = (async ({event, resolve}) => {
const appHandle = (async ({ event, resolve }) => {
logger.debug(event.url.pathname, "API Handle")
logger.debug(`Session Data: ${event.locals.session}`, "API Handle")
logger.debug(event.url.pathname, "APP Handle")
logger.debug(`Session Data: ${event.locals.session}`, "APP Handle")
if(!event.url.pathname.startsWith("/app/program")) {
if (!event.url.pathname.startsWith("/app/program")) {
// next handle
return await resolve(event)
}
@ -57,8 +71,31 @@ const appHandle = (async ({event, resolve}) => {
}) satisfies Handle
const appNonAuthHandle = (async ({ event, resolve }) => {
logger.debug(`Session Data: ${event.locals.session}`, "APP Non Auth")
if (
!event.url.pathname.startsWith("/app/login") &&
!event.url.pathname.startsWith("/app/register")
) {
// next handle
return await resolve(event)
}
// It's for frontend, should redirect
if (event.locals.session) {
return redirect(302, "/app/program")
}
return await resolve(event)
}) satisfies Handle
export const handles = sequence(
sessionConstructorHandle,
apiHandle,
appHandle
appHandle,
appNonAuthHandle
)

View File

@ -1,19 +1,23 @@
import type { ServerInit } from '@sveltejs/kit';
import { handles } from './handles/handle';
import { SSLSnifferApp } from '$lib/db-utils/sqlite';
import { DatabaseBrokerManager } from '$lib/broker-utils/SQLite/Database';
import { UserApp } from '$lib/classes/users';
import { UserDBBroker } from '$lib/db-utils/Users';
import { UserDBBroker } from '$lib/broker-utils/SQLite/Users';
import { SessionApp } from '$lib/classes/sessions';
import { SessionDBBroker } from '$lib/db-utils/Sessions';
import { AppData } from '$lib/classes/app-sessions';
import { SessionDBBroker } from '$lib/broker-utils/SQLite/Sessions';
import { AppData } from '$lib/classes/appdata';
import { logger } from '$lib/utils/logger';
import { JoseApp } from '$lib/utils/jtw-utils';
export const init: ServerInit = async () => {
logger.debug("Starting app", "App Init")
if(!DatabaseBrokerManager.ready) {
DatabaseBrokerManager.init()
}
SSLSnifferApp.init()
UserApp.init(
new UserDBBroker()
)

View File

@ -2,7 +2,7 @@ import { DB_PATH } from "$lib/utils/constants";
import { logger } from "$lib/utils/logger";
import { Database, Statement } from "bun:sqlite";
export class SSLSnifferApp {
export class DatabaseBrokerManager {
private static initialized = false
@ -13,13 +13,17 @@ export class SSLSnifferApp {
logger.debug("Initializing Database", "SSLSnifferApp")
if (SSLSnifferApp.initialized) {
if (DatabaseBrokerManager.initialized) {
logger.debug("database initialized Twice?", "SSLSnifferApp")
throw new Error("SSLSniffer has already been initialized")
}
SSLSnifferApp.db = SSLSnifferApp.initDatabase()
SSLSnifferApp.initialized = true
DatabaseBrokerManager.db = DatabaseBrokerManager.initDatabase()
DatabaseBrokerManager.initialized = true
}
public static get ready() {
return DatabaseBrokerManager.initialized
}
@ -27,7 +31,7 @@ export class SSLSnifferApp {
logger.debug(`Statement: ${query}`, "SQLite Query Preparation")
return SSLSnifferApp.db.prepare(query)
return DatabaseBrokerManager.db.prepare(query)
}
private static initDatabase() {
@ -56,7 +60,7 @@ export class SSLSnifferApp {
// Change of variable to make it more readable
const forceful = !graceful
SSLSnifferApp.db.close(forceful)
DatabaseBrokerManager.db.close(forceful)
}
}

View File

@ -1,6 +1,6 @@
import { Session, type ISessionBroker } from "$lib/classes/sessions"
import { logger } from "$lib/utils/logger"
import { SSLSnifferApp } from "./sqlite"
import { DatabaseBrokerManager } from "./Database"
class SessionDB {
@ -40,7 +40,7 @@ export class SessionDBBroker implements ISessionBroker {
createTable(): void {
const stmt = SSLSnifferApp.prepare(
const stmt = DatabaseBrokerManager.prepare(
`
CREATE TABLE IF NOT EXISTS sessions (
session_id INTEGER PRIMARY KEY AUTOINCREMENT,
@ -70,7 +70,7 @@ export class SessionDBBroker implements ISessionBroker {
const token : string = crypto.randomUUID();
// Insert into DB
const stmt = SSLSnifferApp.prepare(
const stmt = DatabaseBrokerManager.prepare(
`
INSERT INTO sessions (user_id, session_token)
VALUES (@userID, @token);
@ -129,7 +129,7 @@ export class SessionDBBroker implements ISessionBroker {
private getSessionDBFromToken(token: string): SessionDB | null {
logger.debug(`token: ${token}`, "DB Session from Token")
const stmt = SSLSnifferApp.prepare(
const stmt = DatabaseBrokerManager.prepare(
`
SELECT session_id, user_id, session_token
FROM sessions
@ -147,7 +147,7 @@ export class SessionDBBroker implements ISessionBroker {
}
private getSessionDBFromUserID(userID: number): SessionDB | null {
const stmt = SSLSnifferApp.prepare(
const stmt = DatabaseBrokerManager.prepare(
`
SELECT session_id, user_id, session_token
FROM sessions
@ -165,7 +165,7 @@ export class SessionDBBroker implements ISessionBroker {
private getSessionDBFromSessionID(sessionID: number): SessionDB | null {
const stmt = SSLSnifferApp.prepare(
const stmt = DatabaseBrokerManager.prepare(
`
SELECT session_id, user_id, session_token
FROM sessions

View File

@ -1,7 +1,7 @@
import type { Session, SessionApp } from "$lib/classes/sessions";
import { User, type IUserBroker } from "$lib/classes/users";
import { logger } from "$lib/utils/logger";
import { SSLSnifferApp } from "./sqlite";
import { DatabaseBrokerManager } from "./Database";
import * as argon2 from "argon2";
@ -37,7 +37,7 @@ export class UserDBBroker implements IUserBroker {
public createTable(): void {
const stmt = SSLSnifferApp.prepare(
const stmt = DatabaseBrokerManager.prepare(
`
CREATE TABLE IF NOT EXISTS users (
user_id INTEGER PRIMARY KEY AUTOINCREMENT,
@ -54,7 +54,7 @@ export class UserDBBroker implements IUserBroker {
this.validateUniqueness(username)
const insertUser = SSLSnifferApp.prepare(
const insertUser = DatabaseBrokerManager.prepare(
`
INSERT INTO users (username, password_hash)
VALUES (@username, @password);
@ -127,7 +127,7 @@ export class UserDBBroker implements IUserBroker {
}
const passwordHash = await argon2.hash(newPassword)
const stmt = SSLSnifferApp.prepare(
const stmt = DatabaseBrokerManager.prepare(
`
UPDATE users
SET password_hash = @newPassword
@ -173,7 +173,7 @@ export class UserDBBroker implements IUserBroker {
}
private getUserFromUsername(username: string): UserDB | null {
const stmt = SSLSnifferApp.prepare(
const stmt = DatabaseBrokerManager.prepare(
`
SELECT user_id, username, password_hash
FROM users
@ -201,7 +201,7 @@ export class UserDBBroker implements IUserBroker {
private getUserFromUserID(userID: number): UserDB | null {
const stmt = SSLSnifferApp.prepare(
const stmt = DatabaseBrokerManager.prepare(
`
SELECT user_id, username, password_hash
FROM users

View File

@ -3,6 +3,7 @@ import { SessionApp, type Session } from "./sessions";
import { UserApp, type User } from "./users";
import { JoseApp } from "$lib/utils/jtw-utils";
import { logger } from "$lib/utils/logger";
import { SESSION_COOKIE_NAME } from "$lib/utils/constants";
export class AppData {
@ -28,7 +29,7 @@ export class AppData {
public static async extractAppDataFromCookies(cookies: Cookies) {
const encodedSessionToken = cookies.get("session")
const encodedSessionToken = cookies.get(SESSION_COOKIE_NAME)
logger.debug(`Session Cookie: ${encodedSessionToken}`, "APP Session Building 1")
@ -40,7 +41,18 @@ export class AppData {
logger.debug(`Session Cookie: ${decodedSessionToken}`, "APP Session Building 2")
const sessionToken = (await JoseApp.verifyObject(decodedSessionToken)).token
const candidateToken = (await JoseApp.verifyObject(decodedSessionToken))
if (!candidateToken) {
cookies.delete(SESSION_COOKIE_NAME, {
path: "/"
})
return null
}
const sessionToken : string = candidateToken.token
logger.debug(`Session Token: ${sessionToken}`, "APP Session Building 3")
@ -60,4 +72,8 @@ export class AppData {
)
}
public toString() {
return `User:\t${this.user}\nSession:\t${this.session}`
}
}

View File

@ -1,119 +0,0 @@
import type { NginxProtocol } from "$lib/enums/protocols"
import { isPortAvailable, validatePort } from "$lib/utils/ports-utils"
// TODO: inherit from a super class
/**
* This class represents an SSL Termination Endpoint.
*
* While it's possible to create it directly, it is
* discouraged in favor of the Factory methods as it does
* more checks than this class
*/
export class SSLTerminationEndpoint {
public sslPort: number
public clearPort: number
public servicePort: number
public protocol: NginxProtocol
public certificateURI: string
public privateKeyURI: string
constructor(
sslPort: number,
clearPort: number,
servicePort: number,
protocol: NginxProtocol,
certificateURI: string,
privateKeyURI: string
) {
validatePort(sslPort)
validatePort(clearPort)
validatePort(servicePort)
// TODO: check for file existance
this.sslPort = sslPort
this.clearPort = clearPort
this.servicePort = servicePort
this.protocol = protocol
this.certificateURI = certificateURI
this.privateKeyURI = privateKeyURI
}
}
export class SSLTerminationEndpointFactory {
/**
* Creates an SSLEndpoint and chooses ports
* automatically
*
* @param servicePort
* @param protocol
* @param certificateURI
* @param privateKeyURI
*/
public static async createSSLEndpoint(
servicePort: number,
protocol: NginxProtocol,
certificateURI: string,
privateKeyURI: string
): Promise<SSLTerminationEndpoint>
public static async createSSLEndpoint(
servicePort: number,
protocol: NginxProtocol,
certificateURI: string,
privateKeyURI: string,
sslPort?: number,
clearPort?: number,
): Promise<SSLTerminationEndpoint> {
if (!sslPort) {
sslPort = await SSLTerminationEndpointFactory.generatePort()
}
if (!clearPort) {
clearPort = await SSLTerminationEndpointFactory.generatePort()
}
return new SSLTerminationEndpoint(
sslPort,
clearPort,
servicePort,
protocol,
certificateURI,
privateKeyURI
)
}
private static async generatePort() {
const MIN_PORT = 1025
const MAX_PORT = 65535
const MAX_RETRIES = 100
let counter = 0
while (counter < MAX_RETRIES) {
let candidatePort = Math.trunc(
Math.random() * (MAX_PORT - MIN_PORT) + MIN_PORT
)
if (await isPortAvailable(candidatePort)) {
return candidatePort
}
counter++
}
// UGLY: change this to a more specific error
throw Error(`Couldn't find an available port in less than ${MAX_RETRIES}`)
}
}

View File

@ -0,0 +1,10 @@
import type { EndpointType } from "$lib/enums/endpoints";
export interface IEndpoint {
type: EndpointType
name: string
path: string
hash: string
}

View File

@ -1,5 +1,6 @@
export interface ISessionBroker {
// TODO: change in init()
createTable(): void
createSessionFromUserID(userID: number): Session
getSessionFromUserID(userID: number): Session | null
@ -23,6 +24,10 @@ export class Session {
this.sessionToken = sessionToken
}
public toString() {
return this.sessionToken
}
}
export class SessionApp {

View File

@ -0,0 +1,253 @@
import { EndpointType } from "$lib/enums/endpoints"
import type { NginxProtocol } from "$lib/enums/protocols"
import { doesFileExists } from "$lib/utils/filesystem-utils"
import { isPortAvailable, validatePort } from "$lib/utils/ports-utils"
import type { init } from "../../hooks.server"
import type { IEndpoint } from "./endpoints"
// TODO: inherit from a super class
export interface ISSLTerminationBroker {
/**
* Initialize the Broker and everything related to it
*/
init(): Promise<void>
// Creation should throw if something goes wrong
// with reasons why
createSSLTerminationSimple(
name: string,
servicePort: number,
serviceEndpoint: string,
certificateURI: string,
privateKeyURI: string
): Promise<SSLTermination>
createSSLTerminationComplete(
name: string,
sslPort: number,
clearPort: number,
servicePort: number,
serviceEndpoint: string,
certificateURI: string,
privateKeyURI: string
): Promise<SSLTermination>
// Getting endpoints may be null, react over them
getSSLTerminationByName(
name: string
): Promise<SSLTermination|null>
// Throw if something goes wrong
modifySSLTerminationByName(
name: string,
changes: SSLTerminationChanges
): Promise<SSLTermination>
deleteSSLTerminationByName(
name: string
): Promise<SSLTermination|null>
getAllSSLTerminations(): Promise<SSLTermination[]>
}
/**
* This class represents an SSL Termination Endpoint.
*
* While it's possible to create it directly, it is
* discouraged in favor of the Factory methods as it does
* more checks than this class
*/
export class SSLTermination implements IEndpoint {
private static _type: EndpointType = EndpointType.SSL_TERMINATION
public path: string
public hash: string
public name: string
public sslPort: number
public clearPort: number
public servicePort: number
public serviceEndpoint: string
public protocol: NginxProtocol
public certificateURI: string
public privateKeyURI: string
public get type() {
return SSLTermination._type
}
constructor(
name: string,
path: string,
hash: string,
sslPort: number,
clearPort: number,
servicePort: number,
serviceEndpoint: string,
protocol: NginxProtocol,
certificateURI: string,
privateKeyURI: string
) {
validatePort(sslPort)
validatePort(clearPort)
validatePort(servicePort)
this.name = name
this.path = path
this.hash = hash
this.sslPort = sslPort
this.clearPort = clearPort
this.servicePort = servicePort
this.serviceEndpoint = serviceEndpoint
this.protocol = protocol
this.certificateURI = certificateURI
this.privateKeyURI = privateKeyURI
}
}
type SSLTerminationChanges = {
name?: string,
sslPort?: number,
clearPort?: number,
servicePort?: number,
serviceEndpoint?: string,
protocol?: NginxProtocol,
certificateURI?: string,
privateKeyURI?: string
}
export class SSLTerminationEndpointApp {
private static initialized: boolean = false
private static broker: ISSLTerminationBroker
public static get ready() {
return SSLTerminationEndpointApp.initialized
}
public static init(broker: ISSLTerminationBroker) {
SSLTerminationEndpointApp.assureNotInitialized()
SSLTerminationEndpointApp.broker = broker
broker.init()
SSLTerminationEndpointApp.initialized = true
}
// Creation should throw if something goes wrong
// with reasons why
public static async createSSLTerminationSimple(
name: string,
servicePort: number,
serviceEndpoint: string,
certificateURI: string,
privateKeyURI: string
): Promise<SSLTermination> {
SSLTerminationEndpointApp.assureInitialized()
return await this.broker.createSSLTerminationSimple(
name,
servicePort,
serviceEndpoint,
certificateURI,
privateKeyURI
)
}
public static async createSSLTerminationComplete(
name: string,
sslPort: number,
clearPort: number,
servicePort: number,
serviceEndpoint: string,
certificateURI: string,
privateKeyURI: string
): Promise<SSLTermination> {
SSLTerminationEndpointApp.assureInitialized()
return await this.broker.createSSLTerminationComplete(
name,
sslPort,
clearPort,
servicePort,
serviceEndpoint,
certificateURI,
privateKeyURI
)
}
// Getting endpoints may be null, react over them
public static async getSSLTerminationByName(
name: string
): Promise<SSLTermination|null> {
SSLTerminationEndpointApp.assureInitialized()
return await this.broker.getSSLTerminationByName(
name
)
}
// Throw if something goes wrong
public static async modifySSLTerminationByName(
name: string,
changes: SSLTerminationChanges
): Promise<SSLTermination> {
SSLTerminationEndpointApp.assureInitialized()
return await this.broker.modifySSLTerminationByName(
name,
changes
)
}
public static async deleteSSLTerminationByName(
name: string
): Promise<SSLTermination|null> {
SSLTerminationEndpointApp.assureInitialized()
return await this.broker.deleteSSLTerminationByName(
name
)
}
public static async getAllSSLTerminations(): Promise<SSLTermination[]> {
SSLTerminationEndpointApp.assureInitialized()
return await this.broker.getAllSSLTerminations()
}
private static assureNotInitialized() {
if (SSLTerminationEndpointApp.initialized) {
// UGLY: more specific
throw new Error("SSLTerminationEndpointApp has been already initialized")
}
}
private static assureInitialized() {
if (SSLTerminationEndpointApp.initialized) {
// UGLY: more specific
throw new Error("SSLTerminationEndpointApp has not been initialized yet")
}
}
}

View File

@ -2,7 +2,7 @@ import type { Session } from "./sessions"
export interface IUserBroker {
// TODO: change in init()
createTable(): void
createUser(username: string, password: string): Promise<User>
getUser(username: string, password: string): Promise<User|null>
@ -24,6 +24,10 @@ export class User {
this.username = username
}
public toString() {
return `userID:\t${this.userID}\nusername:\t${this.username}`
}
}

View File

@ -0,0 +1,6 @@
export enum EndpointType {
SSL_TERMINATION = "SSL-Termination",
MANUAL = "Manual"
}

View File

@ -3,4 +3,20 @@ export const DB_PATH = "src/db/db.sqlite"
export const SERVER_PRIVATE_DIR = "src/private"
export const SERVER_PRIVATE_KEY_PATH = `${SERVER_PRIVATE_DIR}/key.pem`
export const SERVER_PUBLIC_KEY_PATH = `${SERVER_PRIVATE_DIR}/pub.pem`
export const DEBUG = import.meta.env.DEV
export const DEBUG = import.meta.env.DEV
// NGINX
export const NGINX_BASE = "/etc/nginx"
// API ROUTES
export const API_BASE = "/api"
export const PROTECTED_API_BASE = `${API_BASE}/program`
// APP ROUTES
export const APP_BASE = "/app"
export const PROTECTED_APP_BASE = `${APP_BASE}/program`
export const APP_HOME = `${PROTECTED_APP_BASE}/home`
// Cookies
export const SESSION_COOKIE_NAME = "session"

View File

@ -1,5 +1,5 @@
import * as jose from "jose";
import { loadFile } from "./filesystem-utils";
import { doesFileExists, loadFile } from "./filesystem-utils";
import { SERVER_PRIVATE_KEY_PATH, SERVER_PUBLIC_KEY_PATH } from "./constants";
import { openSSLInit } from "./openssl-utils";
import { logger } from "./logger";
@ -16,7 +16,14 @@ export class JoseApp {
JoseApp.assureNotInitialized()
await openSSLInit()
if (
!await doesFileExists(SERVER_PRIVATE_KEY_PATH) ||
!await doesFileExists(SERVER_PUBLIC_KEY_PATH)
) {
await openSSLInit()
}
JoseApp.privateKey = await JoseApp.loadPrivateKey()
JoseApp.publicKey = await JoseApp.loadPublicKey()
@ -68,7 +75,7 @@ export class JoseApp {
public static async verifyObject(jwt: string) {
JoseApp.assureInitialized()
let _payload: Uint8Array
try {
@ -77,7 +84,7 @@ export class JoseApp {
JoseApp.publicKey
)
_payload = payload
} catch(err) {
} catch (err) {
logger.debug(`Error: ${err}`, "JOSE Verify")
return null
}

View File

@ -1,8 +1,8 @@
import { error, json, text, type Cookies } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { UserApp } from '$lib/classes/users';
import { User, UserApp } from '$lib/classes/users';
import { SessionApp } from '$lib/classes/sessions';
import { AppData } from '$lib/classes/app-sessions';
import { AppData } from '$lib/classes/appdata';
import { logger } from '$lib/utils/logger';
/***********************************************************
@ -45,12 +45,18 @@ export const POST: RequestHandler = async ({ request, locals, cookies }) => {
}
userJson = tmpJSON
let user: User | null
// If this fails, should be a 500
const user = await UserApp.getUser(
userJson.username,
userJson.password
)
try {
user = await UserApp.getUser(
userJson.username,
userJson.password
)
} catch {
return error(400, "The provided credentials are non correct")
}
if (!user) {
return error(400, "The provided credentials are not correct")

View File

@ -0,0 +1,51 @@
import { error, json, text, type Cookies } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { User, UserApp } from '$lib/classes/users';
import { SessionApp } from '$lib/classes/sessions';
import { AppData } from '$lib/classes/appdata';
import { logger } from '$lib/utils/logger';
import { SESSION_COOKIE_NAME } from '$lib/utils/constants';
/***********************************************************
*
* Author: Christian Risi 26/06/2025
*
*
*
*
***********************************************************/
export const GET: RequestHandler = async ({ request, locals, cookies }) => {
const req: Request = request
const local: App.Locals = locals
const cookie: Cookies = cookies
logger.debug(`locals: ${local.session}`, "API Logout")
cookie.delete(
SESSION_COOKIE_NAME,
{
path: "/"
}
)
return text("OK")
}
export const fallback: RequestHandler = async ({ }) => {
// TODO: return method not allowed
const res = new Response(
null,
{
status: 405,
statusText: "Method Not Allowed",
headers: {
Allow: "GET"
}
}
)
return res
};

View File

@ -2,7 +2,7 @@ import { error, json, text, type Cookies } from '@sveltejs/kit';
import type { RequestHandler } from './$types';
import { UserApp, User } from '$lib/classes/users';
import { SessionApp, Session } from '$lib/classes/sessions';
import { AppData } from '$lib/classes/app-sessions';
import { AppData } from '$lib/classes/appdata';
import { logger } from '$lib/utils/logger';
/***********************************************************

View File

@ -1,4 +1,6 @@
<script lang="ts">
import { goto } from "$app/navigation";
import { APP_HOME } from "$lib/utils/constants";
import { redirect } from "@sveltejs/kit";
@ -27,11 +29,12 @@
}
)
if (res.status != 200) {
error = res.statusText
if (res.status !== 200) {
error = `${res.status}: ${(await res.json()).message}`
return
}
redirect(302, "/app/program")
goto(APP_HOME)
}
@ -50,4 +53,6 @@
<span>{error}</span>
{/if}
<a href="/app/register">Register</a>

View File

@ -0,0 +1,3 @@
<h1>Home</h1>
Welcome to SSL-Sniffer

View File

@ -1,4 +1,6 @@
<script lang="ts">
import { goto } from "$app/navigation";
import { APP_HOME } from "$lib/utils/constants";
import { redirect } from "@sveltejs/kit";
@ -28,9 +30,12 @@
)
if (res.status != 201) {
error = res.statusText
error = `${res.status}: ${(await res.json()).message}`
return
}
goto(APP_HOME)
}
</script>
@ -49,4 +54,6 @@
<span>{error}</span>
{/if}
<a href="/app/login">Login</a>