mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-23 15:36:33 +00:00
refactor(nest): inject DatabaseService in db-using services
This commit is contained in:
@@ -14,6 +14,8 @@ vi.mock('../../../src/services/notifications', () => ({ getAppUrl: () => 'https:
|
||||
|
||||
const { getDb } = vi.hoisted(() => ({ getDb: { current: null as unknown } }));
|
||||
vi.mock('../../../src/db/database', () => ({ get db() { return getDb.current; } }));
|
||||
import { db as dbConn } from '../../../src/db/database';
|
||||
import { DatabaseService } from '../../../src/nest/database/database.service';
|
||||
|
||||
// The token POST now runs through the SSRF guard (ssrfGuard.safeFetchLlm), which
|
||||
// resolves the host before fetching. Stub DNS so the fake provider.example host
|
||||
@@ -50,12 +52,12 @@ const NOW = 1_700_000_000_000;
|
||||
|
||||
describe('PluginOAuthService', () => {
|
||||
let svc: PluginOAuthService;
|
||||
beforeEach(() => { getDb.current = freshDb(); svc = new PluginOAuthService(); vi.restoreAllMocks(); dnsState.address = '93.184.216.34'; dnsState.family = 4; });
|
||||
beforeEach(() => { getDb.current = freshDb(); svc = new PluginOAuthService(new DatabaseService(dbConn)); vi.restoreAllMocks(); dnsState.address = '93.184.216.34'; dnsState.family = 4; });
|
||||
|
||||
it('providerConfig returns null unless every piece is present, decrypting the secrets', () => {
|
||||
expect(svc.providerConfig('p')).toMatchObject({ clientId: 'client-123', clientSecret: 'secret-abc', scopes: 'read write' });
|
||||
getDb.current = freshDb({ ...CFG, oauth_client_secret: '' });
|
||||
expect(new PluginOAuthService().providerConfig('p')).toBeNull();
|
||||
expect(new PluginOAuthService(new DatabaseService(dbConn)).providerConfig('p')).toBeNull();
|
||||
});
|
||||
|
||||
it('startConnect builds a PKCE authorize URL + persists a single fresh state per user', () => {
|
||||
@@ -76,18 +78,18 @@ describe('PluginOAuthService', () => {
|
||||
|
||||
it('rejects a non-https / loopback / metadata / internal authorize endpoint', () => {
|
||||
getDb.current = freshDb({ ...CFG, oauth_authorize_url: 'http://provider.example/authorize' });
|
||||
expect(() => new PluginOAuthService().startConnect('p', 42, NOW)).toThrow(/https/);
|
||||
expect(() => new PluginOAuthService(new DatabaseService(dbConn)).startConnect('p', 42, NOW)).toThrow(/https/);
|
||||
getDb.current = freshDb({ ...CFG, oauth_token_url: 'https://127.0.0.1/token' });
|
||||
expect(() => new PluginOAuthService().startConnect('p', 42, NOW)).toThrow(/loopback|private/);
|
||||
expect(() => new PluginOAuthService(new DatabaseService(dbConn)).startConnect('p', 42, NOW)).toThrow(/loopback|private/);
|
||||
// IPv6-literal loopback must not slip past the fast-fail
|
||||
getDb.current = freshDb({ ...CFG, oauth_token_url: 'https://[::1]/token' });
|
||||
expect(() => new PluginOAuthService().startConnect('p', 42, NOW)).toThrow(/loopback/);
|
||||
expect(() => new PluginOAuthService(new DatabaseService(dbConn)).startConnect('p', 42, NOW)).toThrow(/loopback/);
|
||||
// cloud-metadata by literal is refused too
|
||||
getDb.current = freshDb({ ...CFG, oauth_token_url: 'https://169.254.169.254/token' });
|
||||
expect(() => new PluginOAuthService().startConnect('p', 42, NOW)).toThrow(/loopback|metadata/);
|
||||
expect(() => new PluginOAuthService(new DatabaseService(dbConn)).startConnect('p', 42, NOW)).toThrow(/loopback|metadata/);
|
||||
// an internal name suffix is refused
|
||||
getDb.current = freshDb({ ...CFG, oauth_token_url: 'https://idp.internal/token' });
|
||||
expect(() => new PluginOAuthService().startConnect('p', 42, NOW)).toThrow(/local/);
|
||||
expect(() => new PluginOAuthService(new DatabaseService(dbConn)).startConnect('p', 42, NOW)).toThrow(/local/);
|
||||
});
|
||||
|
||||
it('completeCallback verifies state (single-use, user-bound, TTL), exchanges the code, encrypts tokens', async () => {
|
||||
|
||||
Reference in New Issue
Block a user