Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release version v1.0.0-132 #2173

Merged
merged 14 commits into from
Dec 2, 2024
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# Changelog

## v1.0.0-132


### 💅 Refactors

- Create tx context ([fe0776a](https://github.com/undb-io/undb/commit/fe0776a))

### ❤️ Contributors

- Nichenqin ([@nichenqin](http://github.com/nichenqin))

## v1.0.0-131


2 changes: 1 addition & 1 deletion apps/backend/src/app.ts
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ import { container } from "@undb/di"
import { env } from "@undb/env"
import { Graphql } from "@undb/graphql"
import { createLogger } from "@undb/logger"
import { dbMigrate } from "@undb/persistence"
import { dbMigrate } from "@undb/persistence/server"
import { PubSubContext } from "@undb/realtime"
import { IRecordEvent } from "@undb/table"
import { route } from "@undb/trpc"
21 changes: 0 additions & 21 deletions apps/backend/src/db.ts

This file was deleted.

3 changes: 1 addition & 2 deletions apps/backend/src/modules/auth/auth.provider.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { BunSQLiteAdapter, LibSQLAdapter } from "@lucia-auth/adapter-sqlite"
import { container, inject, instanceCachingFactory } from "@undb/di"
import { env } from "@undb/env"
import { Client } from "@undb/persistence"
import { SQLITE_CLIENT } from "@undb/persistence/src/client"
import { Client, SQLITE_CLIENT } from "@undb/persistence/server"
import Database from "bun:sqlite"
import { Adapter, Lucia } from "lucia"

71 changes: 39 additions & 32 deletions apps/backend/src/modules/auth/auth.ts
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ import { None, Option, Some } from "@undb/domain"
import { env } from "@undb/env"
import { createLogger } from "@undb/logger"
import { type IMailService, injectMailService } from "@undb/mail"
import { type IQueryBuilder, getCurrentTransaction, injectQueryBuilder } from "@undb/persistence"
import { type IQueryBuilder, type ITxContext, injectQueryBuilder, injectTxCTX } from "@undb/persistence/server"
import { type ISpaceService, injectSpaceService } from "@undb/space"
import { Context, Elysia, t } from "elysia"
import type { Session, User } from "lucia"
@@ -25,7 +25,6 @@ import { alphabet, generateRandomString, sha256 } from "oslo/crypto"
import { encodeHex } from "oslo/encoding"
import { omit } from "radash"
import { v7 } from "uuid"
import { withTransaction } from "../../db"
import { injectLucia } from "./auth.provider"
import { OAuth } from "./oauth/oauth"

@@ -52,10 +51,12 @@ export class Auth {
private readonly mailService: IMailService,
@injectLucia()
private readonly lucia: Lucia,
@injectTxCTX()
private readonly txContext: ITxContext,
) {}

async #generateEmailVerificationCode(userId: string, email: string): Promise<string> {
const tx = getCurrentTransaction()
const tx = this.txContext.getCurrentTransaction()
await tx.deleteFrom("undb_email_verification_code").where("user_id", "=", userId).execute()
const code = env.UNDB_MOCK_MAIL_CODE || generateRandomString(6, alphabet("0-9"))
await tx
@@ -71,29 +72,32 @@ export class Auth {
}

async #verifyVerificationCode(user: User, code: string): Promise<boolean> {
return (getCurrentTransaction() ?? this.queryBuilder).transaction().execute(async (tx) => {
const databaseCode = await tx
.selectFrom("undb_email_verification_code")
.selectAll()
.where("user_id", "=", user.id)
.executeTakeFirst()
if (!databaseCode || databaseCode.code !== code) {
return false
}
await tx.deleteFrom("undb_email_verification_code").where("id", "=", databaseCode.id).execute()
return this.txContext
.getCurrentTransaction()
.transaction()
.execute(async (tx) => {
const databaseCode = await tx
.selectFrom("undb_email_verification_code")
.selectAll()
.where("user_id", "=", user.id)
.executeTakeFirst()
if (!databaseCode || databaseCode.code !== code) {
return false
}
await tx.deleteFrom("undb_email_verification_code").where("id", "=", databaseCode.id).execute()

if (!isWithinExpirationDate(new Date(databaseCode.expires_at))) {
return false
}
if (databaseCode.email !== user.email) {
return false
}
return true
})
if (!isWithinExpirationDate(new Date(databaseCode.expires_at))) {
return false
}
if (databaseCode.email !== user.email) {
return false
}
return true
})
}

async #createPasswordResetToken(userId: string): Promise<string> {
const db = getCurrentTransaction() ?? this.queryBuilder
const db = this.txContext.getCurrentTransaction()
await db.deleteFrom("undb_password_reset_token").where("user_id", "=", userId).execute()
const tokenId = generateIdFromEntropySize(25) // 40 character
const tokenHash = encodeHex(await sha256(new TextEncoder().encode(tokenId)))
@@ -206,8 +210,9 @@ export class Auth {
},
})

await withTransaction(this.queryBuilder)(async () => {
await getCurrentTransaction()
await this.txContext.withTransaction(async () => {
await this.txContext
.getCurrentTransaction()
.insertInto("undb_user")
.values({
email: adminEmail,
@@ -326,8 +331,9 @@ export class Auth {
},
})

await withTransaction(this.queryBuilder)(async () => {
await getCurrentTransaction()
await this.txContext.withTransaction(async () => {
await this.txContext
.getCurrentTransaction()
.insertInto("undb_user")
.values({
email,
@@ -470,9 +476,9 @@ export class Auth {
.post(
"/api/reset-password",
async (ctx) => {
return withTransaction(this.queryBuilder)(async () => {
return this.txContext.withTransaction(async () => {
const email = ctx.body.email
const tx = getCurrentTransaction() ?? this.queryBuilder
const tx = this.txContext.getCurrentTransaction()
const user = await tx.selectFrom("undb_user").selectAll().where("email", "=", email).executeTakeFirst()
if (!user) {
return new Response(null, {
@@ -505,8 +511,8 @@ export class Auth {
.post(
"/api/reset-password/:token",
async (ctx) => {
return withTransaction(this.queryBuilder)(async () => {
const tx = getCurrentTransaction() ?? this.queryBuilder
return this.txContext.withTransaction(async () => {
const tx = this.txContext.getCurrentTransaction()

const password = ctx.body.password
const verificationToken = ctx.params.token
@@ -589,7 +595,8 @@ export class Auth {
}

await this.lucia.invalidateUserSessions(user.id)
await (getCurrentTransaction() ?? this.queryBuilder)
await this.txContext
.getCurrentTransaction()
.updateTable("undb_user")
.set("email_verified", true)
.where("id", "=", user.id)
@@ -615,7 +622,7 @@ export class Auth {
.get(
"/invitation/:invitationId/accept",
async (ctx) => {
return withTransaction(this.queryBuilder)(async () => {
return this.txContext.withTransaction(async () => {
const { invitationId } = ctx.params
await this.commandBus.execute(new AcceptInvitationCommand({ id: invitationId }))

11 changes: 6 additions & 5 deletions apps/backend/src/modules/auth/oauth/github.ts
Original file line number Diff line number Diff line change
@@ -2,14 +2,13 @@ import { type ISpaceMemberService, injectSpaceMemberService } from "@undb/authz"
import { setContextValue } from "@undb/context/server"
import { singleton } from "@undb/di"
import { createLogger } from "@undb/logger"
import { type IQueryBuilder, getCurrentTransaction, injectQueryBuilder } from "@undb/persistence"
import { type IQueryBuilder, type ITxContext, injectQueryBuilder, injectTxCTX } from "@undb/persistence/server"
import { type ISpaceService, injectSpaceService } from "@undb/space"
import { GitHub } from "arctic"
import { Elysia } from "elysia"
import { type Lucia, generateIdFromEntropySize } from "lucia"
import { serializeCookie } from "oslo/cookie"
import { OAuth2RequestError, generateState } from "oslo/oauth2"
import { withTransaction } from "../../../db"
import { injectLucia } from "../auth.provider"
import { injectGithubProvider } from "./github.provider"

@@ -26,6 +25,8 @@ export class GithubOAuth {
private readonly github: GitHub,
@injectLucia()
private readonly lucia: Lucia,
@injectTxCTX()
private readonly txContext: ITxContext,
) {}

private logger = createLogger(GithubOAuth.name)
@@ -34,7 +35,7 @@ export class GithubOAuth {
return new Elysia()
.get("/login/github", async (ctx) => {
const state = generateState()
const url = await this.github.createAuthorizationURL(state, { scopes: ["user:email"] })
const url = this.github.createAuthorizationURL(state, ["user:email"])
return new Response(null, {
status: 302,
headers: {
@@ -143,8 +144,8 @@ export class GithubOAuth {
})
}
const userId = generateIdFromEntropySize(10) // 16 characters long
const space = await withTransaction(this.queryBuilder)(async () => {
const tx = getCurrentTransaction()
const space = await this.txContext.withTransaction(async () => {
const tx = this.txContext.getCurrentTransaction()
await tx
.insertInto("undb_user")
.values({
13 changes: 6 additions & 7 deletions apps/backend/src/modules/auth/oauth/google.ts
Original file line number Diff line number Diff line change
@@ -2,14 +2,13 @@ import { type ISpaceMemberService, injectSpaceMemberService } from "@undb/authz"
import { setContextValue } from "@undb/context/server"
import { singleton } from "@undb/di"
import { createLogger } from "@undb/logger"
import { type IQueryBuilder, getCurrentTransaction, injectQueryBuilder } from "@undb/persistence"
import { type IQueryBuilder, type ITxContext, injectQueryBuilder, injectTxCTX } from "@undb/persistence/server"
import { type ISpaceService, injectSpaceService } from "@undb/space"
import { Google, generateCodeVerifier } from "arctic"
import { env } from "bun"
import { Elysia } from "elysia"
import { type Lucia, generateIdFromEntropySize } from "lucia"
import { OAuth2RequestError, generateState } from "oslo/oauth2"
import { withTransaction } from "../../../db"
import { injectLucia } from "../auth.provider"
import { injectGoogleProvider } from "./google.provider"

@@ -26,6 +25,8 @@ export class GoogleOAuth {
private readonly google: Google,
@injectLucia()
private readonly lucia: Lucia,
@injectTxCTX()
private readonly txContext: ITxContext,
) {}

private logger = createLogger(GoogleOAuth.name)
@@ -35,9 +36,7 @@ export class GoogleOAuth {
.get("/login/google", async (ctx) => {
const state = generateState()
const codeVerifier = generateCodeVerifier()
const url = await this.google.createAuthorizationURL(state, codeVerifier, {
scopes: ["email", "profile"],
})
const url = this.google.createAuthorizationURL(state, codeVerifier, ["email", "profile"])

ctx.cookie["state"].set({
value: state,
@@ -133,8 +132,8 @@ export class GoogleOAuth {
})
}
const userId = generateIdFromEntropySize(10) // 16 characters long
const space = await withTransaction(this.queryBuilder)(async () => {
const tx = getCurrentTransaction()
const space = await this.txContext.withTransaction(async () => {
const tx = this.txContext.getCurrentTransaction()
await tx
.insertInto("undb_user")
.values({
2 changes: 1 addition & 1 deletion apps/backend/src/modules/file/file.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { type IContext, injectContext } from "@undb/context"
import { singleton } from "@undb/di"
import { injectQueryBuilder, type IQueryBuilder } from "@undb/persistence"
import { injectQueryBuilder, type IQueryBuilder } from "@undb/persistence/server"
import { injectObjectStorage, type IObjectStorage, type IPutObject } from "@undb/table"
import Elysia, { t } from "elysia"

Loading