Skip to content

Commit df90ef4

Browse files
authored
Merge branch 'main' into feature/add-ref-to-search-results
2 parents 22700d9 + 242fd2e commit df90ef4

16 files changed

Lines changed: 56 additions & 25 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [5.0.3] - 2026-06-17
11+
1012
### Changed
1113
- Changed the workspace "Access" page to a "Security" page. [#1303](https://github.com/sourcebot-dev/sourcebot/pull/1303)
1214

@@ -16,6 +18,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1618

1719
### Fixed
1820
- Validated that `SOURCEBOT_ENCRYPTION_KEY` is exactly 32 characters at startup, failing fast with an actionable message instead of a runtime encryption error. [#1305](https://github.com/sourcebot-dev/sourcebot/pull/1305)
21+
- Fixed the web UI crashing when anonymous access is enabled and a request omits the `User-Agent` header (e.g. proxy or health-check probes). [#1309](https://github.com/sourcebot-dev/sourcebot/pull/1309)
22+
- Fixed the Members page crashing when a `User` had a null email. `User.email` is now required (with a backfilling migration), and SSO sign-ins without an email are rejected. [#1310](https://github.com/sourcebot-dev/sourcebot/pull/1310)
1923

2024
## [5.0.2] - 2026-06-11
2125

docker-compose.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ services:
2222
- CONFIG_PATH=/data/config.json
2323
- AUTH_URL=${AUTH_URL:-http://localhost:3000}
2424
- AUTH_SECRET=${AUTH_SECRET:-000000000000000000000000000000000} # CHANGEME: generate via `openssl rand -base64 33`
25-
- SOURCEBOT_ENCRYPTION_KEY=${SOURCEBOT_ENCRYPTION_KEY:-000000000000000000000000000000000} # CHANGEME: generate via `openssl rand -base64 24`
25+
- SOURCEBOT_ENCRYPTION_KEY=${SOURCEBOT_ENCRYPTION_KEY:-00000000000000000000000000000000} # CHANGEME: generate via `openssl rand -base64 24`
2626
- DATABASE_URL=${DATABASE_URL:-postgresql://postgres:postgres@postgres:5432/postgres} # CHANGEME
2727
- REDIS_URL=${REDIS_URL:-redis://redis:6379} # CHANGEME
2828

docs/api-reference/sourcebot-public.openapi.json

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"openapi": "3.0.3",
33
"info": {
44
"title": "Sourcebot Public API",
5-
"version": "v5.0.2",
5+
"version": "v5.0.3",
66
"description": "OpenAPI description for the public Sourcebot REST endpoints used for search, repository listing, and file browsing. Authentication is instance-dependent: API keys are the standard integration mechanism, OAuth bearer tokens are EE-only, and some instances may allow anonymous access."
77
},
88
"tags": [
@@ -1103,8 +1103,7 @@
11031103
"nullable": true
11041104
},
11051105
"email": {
1106-
"type": "string",
1107-
"nullable": true
1106+
"type": "string"
11081107
},
11091108
"createdAt": {
11101109
"type": "string",
@@ -1148,8 +1147,7 @@
11481147
"nullable": true
11491148
},
11501149
"email": {
1151-
"type": "string",
1152-
"nullable": true
1150+
"type": "string"
11531151
},
11541152
"role": {
11551153
"type": "string",
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-- Make `User.email` required (NOT NULL).
2+
--
3+
-- This migration runs automatically on startup (`prisma migrate deploy`), so it must
4+
-- never fail on existing data. Some instances have legacy `User` rows with a NULL
5+
-- email — most commonly OAuth/OIDC accounts created from an identity-provider profile
6+
-- that returned no email. A bare `SET NOT NULL` would error on those rows and brick the
7+
-- upgrade, so we first backfill any NULL email with a deterministic, unique, obviously
8+
-- synthetic placeholder (the `.invalid` TLD is reserved and can never be a real address;
9+
-- keying off the row `id` guarantees uniqueness under the existing unique constraint).
10+
--
11+
-- Going forward, the `signIn` callback in `packages/web/src/auth.ts` rejects OAuth/OIDC
12+
-- sign-ins whose profile has no email, so no new NULL/placeholder rows are created.
13+
-- Operators can identify backfilled accounts with:
14+
-- SELECT id, email FROM "User" WHERE email LIKE 'placeholder-%@no-email.invalid';
15+
UPDATE "User"
16+
SET "email" = 'placeholder-' || "id" || '@no-email.invalid'
17+
WHERE "email" IS NULL;
18+
19+
-- AlterTable
20+
ALTER TABLE "User" ALTER COLUMN "email" SET NOT NULL;

packages/db/prisma/schema.prisma

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@ model Audit {
430430
model User {
431431
id String @id @default(cuid())
432432
name String?
433-
email String? @unique
433+
email String @unique
434434
hashedPassword String?
435435
emailVerified DateTime?
436436
image String?

packages/shared/src/env.server.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ const options = {
342342
// requirement means this must be exactly 32 characters. Generate one with
343343
// `openssl rand -base64 24` (24 random bytes => a 32-character base64 string).
344344
SOURCEBOT_ENCRYPTION_KEY: z.string().length(32, {
345-
message: "SOURCEBOT_ENCRYPTION_KEY must be exactly 32 characters (a 256-bit AES key). Generate one with `openssl rand -base64 24`.",
345+
message: "SOURCEBOT_ENCRYPTION_KEY must be exactly 32 characters (a 256-bit AES key). Generate one with `openssl rand -base64 24`.\nWARNING: Updating this value will invalidate any existing API keys.",
346346
}),
347347
SOURCEBOT_INSTALL_ID: z.string().default("unknown"),
348348
SOURCEBOT_LIGHTHOUSE_URL: z.string().url().default("https://deployments.sourcebot.dev"),

packages/shared/src/version.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
// This file is auto-generated by .github/workflows/release-sourcebot.yml
2-
export const SOURCEBOT_VERSION = "v5.0.2";
2+
export const SOURCEBOT_VERSION = "v5.0.3";

packages/web/src/actions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ export const createAccountRequest = async () => sew(async () => {
443443
baseUrl: deploymentUrl,
444444
requestor: {
445445
name: user.name ?? undefined,
446-
email: user.email!,
446+
email: user.email,
447447
avatarUrl: user.image ?? undefined,
448448
},
449449
orgName: org.name,

packages/web/src/app/(app)/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ export default async function Layout(props: LayoutProps) {
148148
const headersList = await headers();
149149
const cookieStore = await cookies()
150150
const userAgent = headersList.get('user-agent');
151-
const { isMobile } = getSelectorsByUserAgent(userAgent ?? '');
151+
const { isMobile } = userAgent ? getSelectorsByUserAgent(userAgent) : { isMobile: false };
152152

153153
if (isMobile && !cookieStore.has(MOBILE_UNSUPPORTED_SPLASH_SCREEN_DISMISSED_COOKIE_NAME)) {
154154
return (

packages/web/src/app/invite/actions.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,12 @@ export const getInviteInfo = async (inviteId: string) => sew(async () => {
195195
orgImageUrl: invite.org.imageUrl ?? undefined,
196196
host: {
197197
name: invite.host.name ?? undefined,
198-
email: invite.host.email!,
198+
email: invite.host.email,
199199
avatarUrl: invite.host.image ?? undefined,
200200
},
201201
recipient: {
202202
name: user.name ?? undefined,
203-
email: user.email!,
203+
email: user.email,
204204
}
205205
};
206206
});

0 commit comments

Comments
 (0)