mirror of
https://github.com/sourcebot-dev/sourcebot.git
synced 2025-12-15 22:05:23 +00:00
Sourcebot V4 introduces authentication, performance improvements and code navigation. Checkout the [migration guide](https://docs.sourcebot.dev/self-hosting/upgrade/v3-to-v4-guide) for information on upgrading your instance to v4. ### Changed - [**Breaking Change**] Authentication is now required by default. Notes: - When setting up your instance, email / password login will be the default authentication provider. - The first user that logs into the instance is given the `owner` role. ([docs](https://docs.sourcebot.dev/docs/more/roles-and-permissions)). - Subsequent users can request to join the instance. The `owner` can approve / deny requests to join the instance via `Settings` > `Members` > `Pending Requests`. - If a user is approved to join the instance, they are given the `member` role. - Additional login providers, including email links and SSO, can be configured with additional environment variables. ([docs](https://docs.sourcebot.dev/self-hosting/configuration/authentication)). - Clicking on a search result now takes you to the `/browse` view. Files can still be previewed by clicking the "Preview" button or holding `Cmd` / `Ctrl` when clicking on a search result. [#315](https://github.com/sourcebot-dev/sourcebot/pull/315) ### Added - [Sourcebot EE] Added search-based code navigation, allowing you to jump between symbol definition and references when viewing source files. [Read the documentation](https://docs.sourcebot.dev/docs/search/code-navigation). [#315](https://github.com/sourcebot-dev/sourcebot/pull/315) - Added collapsible filter panel. [#315](https://github.com/sourcebot-dev/sourcebot/pull/315) ### Fixed - Improved scroll performance for large numbers of search results. [#315](https://github.com/sourcebot-dev/sourcebot/pull/315)
65 lines
1.9 KiB
TypeScript
65 lines
1.9 KiB
TypeScript
import crypto from 'crypto';
|
|
import { SOURCEBOT_ENCRYPTION_KEY } from './environment';
|
|
|
|
const algorithm = 'aes-256-cbc';
|
|
const ivLength = 16; // 16 bytes for CBC
|
|
|
|
const generateIV = (): Buffer => {
|
|
return crypto.randomBytes(ivLength);
|
|
};
|
|
|
|
export function encrypt(text: string): { iv: string; encryptedData: string } {
|
|
if (!SOURCEBOT_ENCRYPTION_KEY) {
|
|
throw new Error('Encryption key is not set');
|
|
}
|
|
|
|
const encryptionKey = Buffer.from(SOURCEBOT_ENCRYPTION_KEY, 'ascii');
|
|
|
|
const iv = generateIV();
|
|
const cipher = crypto.createCipheriv(algorithm, encryptionKey, iv);
|
|
|
|
let encrypted = cipher.update(text, 'utf8', 'hex');
|
|
encrypted += cipher.final('hex');
|
|
|
|
return { iv: iv.toString('hex'), encryptedData: encrypted };
|
|
}
|
|
|
|
export function hashSecret(text: string): string {
|
|
if (!SOURCEBOT_ENCRYPTION_KEY) {
|
|
throw new Error('Encryption key is not set');
|
|
}
|
|
|
|
return crypto.createHmac('sha256', SOURCEBOT_ENCRYPTION_KEY).update(text).digest('hex');
|
|
}
|
|
|
|
export function generateApiKey(): { key: string; hash: string } {
|
|
if (!SOURCEBOT_ENCRYPTION_KEY) {
|
|
throw new Error('Encryption key is not set');
|
|
}
|
|
|
|
const secret = crypto.randomBytes(32).toString('hex');
|
|
const hash = hashSecret(secret);
|
|
|
|
return {
|
|
key: `sourcebot-${secret}`,
|
|
hash,
|
|
};
|
|
}
|
|
|
|
export function decrypt(iv: string, encryptedText: string): string {
|
|
if (!SOURCEBOT_ENCRYPTION_KEY) {
|
|
throw new Error('Encryption key is not set');
|
|
}
|
|
|
|
const encryptionKey = Buffer.from(SOURCEBOT_ENCRYPTION_KEY, 'ascii');
|
|
|
|
const ivBuffer = Buffer.from(iv, 'hex');
|
|
const encryptedBuffer = Buffer.from(encryptedText, 'hex');
|
|
|
|
const decipher = crypto.createDecipheriv(algorithm, encryptionKey, ivBuffer);
|
|
|
|
let decrypted = decipher.update(encryptedBuffer, undefined, 'utf8');
|
|
decrypted += decipher.final('utf8');
|
|
|
|
return decrypted;
|
|
}
|