Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .dvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.0.6
2.1.4
4 changes: 2 additions & 2 deletions .github/workflows/check-workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ permissions:
contents: read

env:
DENO_VERSION: "2.0.6"
DENO_VERSION: "2.1.4"
DENO_DIR: /home/runner/.deno-cache
SQLITE_DATABASE_LOCATION: ":memory:"
COOKIE_DOMAIN: localhost
Expand Down Expand Up @@ -33,7 +33,7 @@ jobs:

- uses: denoland/setup-deno@v1
with:
deno-version: v2.0.6
deno-version: v2.1.4

- name: Cache Deno dependencies
uses: actions/cache@v3
Expand Down
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ database.sqlite
database2.sqlite
temp
app.log
/backups
/backup
7 changes: 2 additions & 5 deletions backend/actions/send-notification-action.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import {
createNotification,
NotificationDataTypes,
} from "$backend/repository/notification-repository.ts";
import { NotificationDataTypes, repository } from "$db";
import { websocketService } from "$workers/websocket/websocket-service.ts";
import { NotificationAddedResponse } from "$workers/websocket/api/notifications/messages.ts";

export const runSendNotificationAction = async (
notification: NotificationDataTypes,
user_id: number,
): Promise<void> => {
const record = await createNotification({
const record = await repository.notification.createNotification({
data: notification,
user_id,
});
Expand Down
2 changes: 1 addition & 1 deletion backend/middlewares/api-error-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const apiErrorHandler = async (
});
}

console.error(e);
console.error("Error:", e);
return new Response("Server error", {
status: 500,
});
Expand Down
29 changes: 15 additions & 14 deletions backend/passkeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,8 @@ import {
import { loadSessionStateByUserId } from "$backend/session/session.ts";
import { AppSessionData } from "$types";
import { getAppUrl } from "$backend/env.ts";
import {
getRegisteredUserPasskeys,
passkeyExists,
registerPassKey,
updatePasskeyLastUsedAt,
} from "$backend/repository/passkey-repository.ts";
import { logger } from "$backend/logger.ts";
import { getPasskeyById } from "$backend/repository/passkey-repository.ts";
import { repository } from "$db";

export const getRelyingPartyId = () => getAppUrl().hostname;
export const getRelyingPartyOrigin = () => getAppUrl().origin;
Expand Down Expand Up @@ -55,9 +49,10 @@ export const initializePasskeyRegistration = async (
throw new Error("User not found in session or is not logged in.");
}

const registeredPasskeys = await getRegisteredUserPasskeys(
user_id,
);
const registeredPasskeys = await repository.passkey
.getRegisteredUserPasskeys(
user_id,
);

const options: PublicKeyCredentialCreationOptionsJSON =
await generateRegistrationOptions({
Expand Down Expand Up @@ -126,15 +121,19 @@ export const finalizePasskeyRegistration = async (
};
}

if (await passkeyExists(verification.registrationInfo.credentialID)) {
if (
await repository.passkey.passkeyExists(
verification.registrationInfo.credentialID,
)
) {
return {
success: false,
fail_reason:
"This passkey is already registered to this or another account.",
};
}

await registerPassKey({
await repository.passkey.registerPassKey({
noteme_user_id: user_id,
name: getDefaultPasskeyName(
registrationResponse.response.transports ?? [],
Expand Down Expand Up @@ -227,7 +226,7 @@ export const finalizePasskeyAuthentication = async (

const { data } = request;

const passkey = await getPasskeyById(response.id);
const passkey = await repository.passkey.getPasskeyById(response.id);

if (!passkey) {
return { user_id: null, verified: false };
Expand All @@ -249,7 +248,9 @@ export const finalizePasskeyAuthentication = async (
});

if (result.verified) {
await updatePasskeyLastUsedAt(passkey.credential_identifier);
await repository.passkey.updatePasskeyLastUsedAt(
passkey.credential_identifier,
);
}

return {
Expand Down
82 changes: 29 additions & 53 deletions backend/session/session.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { db } from "$backend/database.ts";
import { SessionState } from "$backend/session/mod.ts";
import { sql } from "$lib/kysely-sqlite-dialect/deps.ts";
import { repository, TypedSession } from "$db";

export const loadSessionState = async <T>(
sessionId: string,
Expand All @@ -9,44 +8,35 @@ export const loadSessionState = async <T>(
return null;
}

const result = await db.selectFrom("session")
.select(["key", "data", "user_id"])
.where("key", "=", sessionId)
.where("expires_at", ">", (new Date()).getTime())
.orderBy("expires_at", "desc")
.limit(1)
.executeTakeFirst() ?? null;
const result = await repository.session.getSessionByKey(sessionId) as
| TypedSession<T>
| null;

return toSessionObject(result);
};

export const loadSessionStateByUserId = async <T>(
userId: number,
): Promise<SessionState<T> | null> => {
const result = await db.selectFrom("session")
.select(["key", "data", "user_id"])
.where("user_id", "=", userId)
.where("expires_at", ">", (new Date()).getTime())
.orderBy("expires_at", "desc")
.limit(1)
.executeTakeFirst() ?? null;
const result = await repository.session.getSessionByUserId(userId) as
| TypedSession<T>
| null;

return toSessionObject(result);
};

const toSessionObject = <T>(
result: { key: string; data: string; user_id: number } | null,
result: { key: string; data: T; user_id: number } | null,
): SessionState<T> | null => {
try {
if (!result) {
return null;
}

const data = result ? JSON.parse(result.data) : null;
return createSessionStateObject(result.key, result.user_id, data);
} catch {
if (!result) {
return null;
}

return createSessionStateObject(
result.key,
result.user_id,
result.data,
);
};

export const createSessionState = async <T>(
Expand All @@ -63,42 +53,28 @@ export const setSession = async <T>(
userId: number,
data: T,
): Promise<void> => {
const existingRow = await db.selectFrom("session")
.where("key", "=", sessionId)
.where("expires_at", ">", (new Date()).getTime())
.select(sql.lit("1").as("one"))
.executeTakeFirst();

const dataString = JSON.stringify(data);
const existingRow = await repository.session.sessionExists(sessionId);

if (existingRow) {
await db.updateTable("session")
.set({
data: dataString,
})
.where("key", "=", sessionId)
.execute();
await repository.session.updateSessionData({
key: sessionId,
data,
});
} else {
await db.insertInto("session")
.values({
data: dataString,
key: sessionId,
user_id: userId,
expires_at: (new Date()).getTime() +
+(Deno.env.get("COOKIE_MAX_AGE_SECONDS") ?? 43200) * 1000,
})
.execute();
await repository.session.createNewSession({
data,
key: sessionId,
user_id: userId,
expires_at: (new Date()).getTime() +
+(Deno.env.get("COOKIE_MAX_AGE_SECONDS") ?? 43200) * 1000,
});
}

await db.deleteFrom("session")
.where("expires_at", "<", (new Date()).getTime())
.execute();
await repository.session.deleteExpiredSessions();
};

export const destroySession = async (userId: number) => {
await db.deleteFrom("session")
.where("user_id", "=", userId)
.execute();
await repository.session.deleteSessionByUserId(userId);
};

const createSessionStateObject = <T>(
Expand Down
14 changes: 14 additions & 0 deletions bootstrap.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { initializeServices } from "$workers/mod.ts";
import { loadEnvironment } from "$backend/env.ts";
import { setLoggerName } from "$backend/logger.ts";
import { initTempLocation } from "$backend/temp.ts";

export const bootstrap = async () => {
loadEnvironment();

setLoggerName("backend");

await initTempLocation();

await initializeServices();
};
2 changes: 1 addition & 1 deletion cli/add-user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Command } from "$cli/deps.ts";
import {
checkIfUserExists,
createUserRecord,
} from "$backend/repository/user-repository.ts";
} from "$workers/database/query/user-repository.ts";
import { logger } from "$backend/logger.ts";

export const addUser = new Command()
Expand Down
8 changes: 4 additions & 4 deletions deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@
"exclude": ["**/_fresh/*"],
"fmt": { "indentWidth": 4 },
"imports": {
"$fresh/": "https://deno.land/x/fresh@1.7.1/",
"preact": "https://esm.sh/preact@10.19.6",
"preact/": "https://esm.sh/preact@10.19.6/",
"$fresh/": "https://deno.land/x/fresh@1.7.3/",
"preact": "https://esm.sh/preact@10.22.0",
"preact/": "https://esm.sh/preact@10.22.0/",
"@preact/signals": "https://esm.sh/*@preact/signals@1.2.2",
"@preact/signals-core": "https://esm.sh/*@preact/signals-core@1.5.1",
"tailwindcss": "npm:tailwindcss@3.3.5",
Expand All @@ -39,7 +39,7 @@
"$cli/": "./cli/",
"$lib/": "./lib/",
"$types": "./types/mod.ts",
"$tests/": "./tests/"
"$db": "./workers/database/lib.ts"
},
"compilerOptions": { "jsx": "react-jsx", "jsxImportSource": "preact" },
"nodeModulesDir": "auto"
Expand Down
Loading
Loading