Major Enhancement: NestJS Migration + CASL Authorization + Error Handling
Some checks failed
CI/CD Pipeline / Backend Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Tests (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
Some checks failed
CI/CD Pipeline / Backend Tests (push) Has been cancelled
CI/CD Pipeline / Frontend Tests (push) Has been cancelled
CI/CD Pipeline / Build Docker Images (push) Has been cancelled
CI/CD Pipeline / Security Scan (push) Has been cancelled
CI/CD Pipeline / Deploy to Staging (push) Has been cancelled
CI/CD Pipeline / Deploy to Production (push) Has been cancelled
Complete rewrite from Express to NestJS with enterprise-grade features: ## Backend Improvements - Migrated from Express to NestJS 11.0.1 with TypeScript - Implemented Prisma ORM 7.3.0 for type-safe database access - Added CASL authorization system replacing role-based guards - Created global exception filters with structured logging - Implemented Auth0 JWT authentication with Passport.js - Added vehicle management with conflict detection - Enhanced event scheduling with driver/vehicle assignment - Comprehensive error handling and logging ## Frontend Improvements - Upgraded to React 19.2.0 with Vite 7.2.4 - Implemented CASL-based permission system - Added AbilityContext for declarative permissions - Created ErrorHandler utility for consistent error messages - Enhanced API client with request/response logging - Added War Room (Command Center) dashboard - Created VIP Schedule view with complete itineraries - Implemented Vehicle Management UI - Added mock data generators for testing (288 events across 20 VIPs) ## New Features - Vehicle fleet management (types, capacity, status tracking) - Complete 3-day Jamboree schedule generation - Individual VIP schedule pages with PDF export (planned) - Real-time War Room dashboard with auto-refresh - Permission-based navigation filtering - First user auto-approval as administrator ## Documentation - Created CASL_AUTHORIZATION.md (comprehensive guide) - Created ERROR_HANDLING.md (error handling patterns) - Updated CLAUDE.md with new architecture - Added migration guides and best practices ## Technical Debt Resolved - Removed custom authentication in favor of Auth0 - Replaced role checks with CASL abilities - Standardized error responses across API - Implemented proper TypeScript typing - Added comprehensive logging Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
4
backend-old-20260125/dist/config/database.d.ts
vendored
Normal file
4
backend-old-20260125/dist/config/database.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import { Pool } from 'pg';
|
||||
declare const pool: Pool;
|
||||
export default pool;
|
||||
//# sourceMappingURL=database.d.ts.map
|
||||
1
backend-old-20260125/dist/config/database.d.ts.map
vendored
Normal file
1
backend-old-20260125/dist/config/database.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/config/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAK1B,QAAA,MAAM,IAAI,MAKR,CAAC;AAWH,eAAe,IAAI,CAAC"}
|
||||
23
backend-old-20260125/dist/config/database.js
vendored
Normal file
23
backend-old-20260125/dist/config/database.js
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const pg_1 = require("pg");
|
||||
const dotenv_1 = __importDefault(require("dotenv"));
|
||||
dotenv_1.default.config();
|
||||
const pool = new pg_1.Pool({
|
||||
connectionString: process.env.DATABASE_URL || 'postgresql://postgres:changeme@localhost:5432/vip_coordinator',
|
||||
max: 20,
|
||||
idleTimeoutMillis: 30000,
|
||||
connectionTimeoutMillis: 2000,
|
||||
});
|
||||
// Test the connection
|
||||
pool.on('connect', () => {
|
||||
console.log('✅ Connected to PostgreSQL database');
|
||||
});
|
||||
pool.on('error', (err) => {
|
||||
console.error('❌ PostgreSQL connection error:', err);
|
||||
});
|
||||
exports.default = pool;
|
||||
//# sourceMappingURL=database.js.map
|
||||
1
backend-old-20260125/dist/config/database.js.map
vendored
Normal file
1
backend-old-20260125/dist/config/database.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/config/database.ts"],"names":[],"mappings":";;;;;AAAA,2BAA0B;AAC1B,oDAA4B;AAE5B,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,MAAM,IAAI,GAAG,IAAI,SAAI,CAAC;IACpB,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,+DAA+D;IAC7G,GAAG,EAAE,EAAE;IACP,iBAAiB,EAAE,KAAK;IACxB,uBAAuB,EAAE,IAAI;CAC9B,CAAC,CAAC;AAEH,sBAAsB;AACtB,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACtB,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;AACpD,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;IACvB,OAAO,CAAC,KAAK,CAAC,gCAAgC,EAAE,GAAG,CAAC,CAAC;AACvD,CAAC,CAAC,CAAC;AAEH,kBAAe,IAAI,CAAC"}
|
||||
17
backend-old-20260125/dist/config/mockDatabase.d.ts
vendored
Normal file
17
backend-old-20260125/dist/config/mockDatabase.d.ts
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
declare class MockDatabase {
|
||||
private users;
|
||||
private vips;
|
||||
private drivers;
|
||||
private scheduleEvents;
|
||||
private adminSettings;
|
||||
constructor();
|
||||
query(text: string, params?: any[]): Promise<any>;
|
||||
connect(): Promise<{
|
||||
query: (text: string, params?: any[]) => Promise<any>;
|
||||
release: () => void;
|
||||
}>;
|
||||
end(): Promise<void>;
|
||||
on(event: string, callback: Function): void;
|
||||
}
|
||||
export default MockDatabase;
|
||||
//# sourceMappingURL=mockDatabase.d.ts.map
|
||||
1
backend-old-20260125/dist/config/mockDatabase.d.ts.map
vendored
Normal file
1
backend-old-20260125/dist/config/mockDatabase.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"mockDatabase.d.ts","sourceRoot":"","sources":["../../src/config/mockDatabase.ts"],"names":[],"mappings":"AAyBA,cAAM,YAAY;IAChB,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,IAAI,CAAmC;IAC/C,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,aAAa,CAAkC;;IA8BjD,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAiGjD,OAAO;sBAjGK,MAAM,WAAW,GAAG,EAAE,KAAG,OAAO,CAAC,GAAG,CAAC;;;IAyGjD,GAAG;IAIT,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ;CAKrC;AAED,eAAe,YAAY,CAAC"}
|
||||
137
backend-old-20260125/dist/config/mockDatabase.js
vendored
Normal file
137
backend-old-20260125/dist/config/mockDatabase.js
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
class MockDatabase {
|
||||
constructor() {
|
||||
this.users = new Map();
|
||||
this.vips = new Map();
|
||||
this.drivers = new Map();
|
||||
this.scheduleEvents = new Map();
|
||||
this.adminSettings = new Map();
|
||||
// Add a test admin user
|
||||
const adminId = '1';
|
||||
this.users.set(adminId, {
|
||||
id: adminId,
|
||||
email: 'admin@example.com',
|
||||
name: 'Test Admin',
|
||||
role: 'admin',
|
||||
created_at: new Date(),
|
||||
updated_at: new Date()
|
||||
});
|
||||
// Add some test VIPs
|
||||
this.vips.set('1', {
|
||||
id: '1',
|
||||
name: 'John Doe',
|
||||
organization: 'Test Org',
|
||||
department: 'Office of Development',
|
||||
transport_mode: 'flight',
|
||||
expected_arrival: '2025-07-25 14:00',
|
||||
needs_airport_pickup: true,
|
||||
needs_venue_transport: true,
|
||||
notes: 'Test VIP',
|
||||
created_at: new Date(),
|
||||
updated_at: new Date()
|
||||
});
|
||||
}
|
||||
async query(text, params) {
|
||||
console.log('Mock DB Query:', text.substring(0, 50) + '...');
|
||||
// Handle user queries
|
||||
if (text.includes('COUNT(*) FROM users')) {
|
||||
return { rows: [{ count: this.users.size.toString() }] };
|
||||
}
|
||||
if (text.includes('SELECT * FROM users WHERE email')) {
|
||||
const email = params?.[0];
|
||||
const user = Array.from(this.users.values()).find(u => u.email === email);
|
||||
return { rows: user ? [user] : [] };
|
||||
}
|
||||
if (text.includes('SELECT * FROM users WHERE id')) {
|
||||
const id = params?.[0];
|
||||
const user = this.users.get(id);
|
||||
return { rows: user ? [user] : [] };
|
||||
}
|
||||
if (text.includes('SELECT * FROM users WHERE google_id')) {
|
||||
const google_id = params?.[0];
|
||||
const user = Array.from(this.users.values()).find(u => u.google_id === google_id);
|
||||
return { rows: user ? [user] : [] };
|
||||
}
|
||||
if (text.includes('INSERT INTO users')) {
|
||||
const id = Date.now().toString();
|
||||
const user = {
|
||||
id,
|
||||
email: params?.[0],
|
||||
name: params?.[1],
|
||||
role: params?.[2] || 'coordinator',
|
||||
google_id: params?.[4],
|
||||
created_at: new Date(),
|
||||
updated_at: new Date()
|
||||
};
|
||||
this.users.set(id, user);
|
||||
return { rows: [user] };
|
||||
}
|
||||
// Handle VIP queries
|
||||
if (text.includes('SELECT v.*') && text.includes('FROM vips')) {
|
||||
const vips = Array.from(this.vips.values());
|
||||
return {
|
||||
rows: vips.map(v => ({
|
||||
...v,
|
||||
flights: []
|
||||
}))
|
||||
};
|
||||
}
|
||||
// Handle admin settings queries
|
||||
if (text.includes('SELECT * FROM admin_settings')) {
|
||||
const settings = Array.from(this.adminSettings.entries()).map(([key, value]) => ({
|
||||
key,
|
||||
value
|
||||
}));
|
||||
return { rows: settings };
|
||||
}
|
||||
// Handle drivers queries
|
||||
if (text.includes('SELECT * FROM drivers')) {
|
||||
const drivers = Array.from(this.drivers.values());
|
||||
return { rows: drivers };
|
||||
}
|
||||
// Handle schedule events queries
|
||||
if (text.includes('SELECT * FROM schedule_events')) {
|
||||
const events = Array.from(this.scheduleEvents.values());
|
||||
return { rows: events };
|
||||
}
|
||||
if (text.includes('INSERT INTO vips')) {
|
||||
const id = Date.now().toString();
|
||||
const vip = {
|
||||
id,
|
||||
name: params?.[0],
|
||||
organization: params?.[1],
|
||||
department: params?.[2] || 'Office of Development',
|
||||
transport_mode: params?.[3] || 'flight',
|
||||
expected_arrival: params?.[4],
|
||||
needs_airport_pickup: params?.[5] !== false,
|
||||
needs_venue_transport: params?.[6] !== false,
|
||||
notes: params?.[7] || '',
|
||||
created_at: new Date(),
|
||||
updated_at: new Date()
|
||||
};
|
||||
this.vips.set(id, vip);
|
||||
return { rows: [vip] };
|
||||
}
|
||||
// Default empty result
|
||||
console.log('Unhandled query:', text);
|
||||
return { rows: [] };
|
||||
}
|
||||
async connect() {
|
||||
return {
|
||||
query: this.query.bind(this),
|
||||
release: () => { }
|
||||
};
|
||||
}
|
||||
// Make compatible with pg Pool interface
|
||||
async end() {
|
||||
console.log('Mock database connection closed');
|
||||
}
|
||||
on(event, callback) {
|
||||
if (event === 'connect') {
|
||||
setTimeout(() => callback(), 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.default = MockDatabase;
|
||||
//# sourceMappingURL=mockDatabase.js.map
|
||||
1
backend-old-20260125/dist/config/mockDatabase.js.map
vendored
Normal file
1
backend-old-20260125/dist/config/mockDatabase.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
292
backend-old-20260125/dist/config/redis.d.ts
vendored
Normal file
292
backend-old-20260125/dist/config/redis.d.ts
vendored
Normal file
@@ -0,0 +1,292 @@
|
||||
declare const redisClient: import("@redis/client").RedisClientType<{
|
||||
graph: {
|
||||
CONFIG_GET: typeof import("@redis/graph/dist/commands/CONFIG_GET");
|
||||
configGet: typeof import("@redis/graph/dist/commands/CONFIG_GET");
|
||||
CONFIG_SET: typeof import("@redis/graph/dist/commands/CONFIG_SET");
|
||||
configSet: typeof import("@redis/graph/dist/commands/CONFIG_SET");
|
||||
DELETE: typeof import("@redis/graph/dist/commands/DELETE");
|
||||
delete: typeof import("@redis/graph/dist/commands/DELETE");
|
||||
EXPLAIN: typeof import("@redis/graph/dist/commands/EXPLAIN");
|
||||
explain: typeof import("@redis/graph/dist/commands/EXPLAIN");
|
||||
LIST: typeof import("@redis/graph/dist/commands/LIST");
|
||||
list: typeof import("@redis/graph/dist/commands/LIST");
|
||||
PROFILE: typeof import("@redis/graph/dist/commands/PROFILE");
|
||||
profile: typeof import("@redis/graph/dist/commands/PROFILE");
|
||||
QUERY: typeof import("@redis/graph/dist/commands/QUERY");
|
||||
query: typeof import("@redis/graph/dist/commands/QUERY");
|
||||
RO_QUERY: typeof import("@redis/graph/dist/commands/RO_QUERY");
|
||||
roQuery: typeof import("@redis/graph/dist/commands/RO_QUERY");
|
||||
SLOWLOG: typeof import("@redis/graph/dist/commands/SLOWLOG");
|
||||
slowLog: typeof import("@redis/graph/dist/commands/SLOWLOG");
|
||||
};
|
||||
json: {
|
||||
ARRAPPEND: typeof import("@redis/json/dist/commands/ARRAPPEND");
|
||||
arrAppend: typeof import("@redis/json/dist/commands/ARRAPPEND");
|
||||
ARRINDEX: typeof import("@redis/json/dist/commands/ARRINDEX");
|
||||
arrIndex: typeof import("@redis/json/dist/commands/ARRINDEX");
|
||||
ARRINSERT: typeof import("@redis/json/dist/commands/ARRINSERT");
|
||||
arrInsert: typeof import("@redis/json/dist/commands/ARRINSERT");
|
||||
ARRLEN: typeof import("@redis/json/dist/commands/ARRLEN");
|
||||
arrLen: typeof import("@redis/json/dist/commands/ARRLEN");
|
||||
ARRPOP: typeof import("@redis/json/dist/commands/ARRPOP");
|
||||
arrPop: typeof import("@redis/json/dist/commands/ARRPOP");
|
||||
ARRTRIM: typeof import("@redis/json/dist/commands/ARRTRIM");
|
||||
arrTrim: typeof import("@redis/json/dist/commands/ARRTRIM");
|
||||
DEBUG_MEMORY: typeof import("@redis/json/dist/commands/DEBUG_MEMORY");
|
||||
debugMemory: typeof import("@redis/json/dist/commands/DEBUG_MEMORY");
|
||||
DEL: typeof import("@redis/json/dist/commands/DEL");
|
||||
del: typeof import("@redis/json/dist/commands/DEL");
|
||||
FORGET: typeof import("@redis/json/dist/commands/FORGET");
|
||||
forget: typeof import("@redis/json/dist/commands/FORGET");
|
||||
GET: typeof import("@redis/json/dist/commands/GET");
|
||||
get: typeof import("@redis/json/dist/commands/GET");
|
||||
MERGE: typeof import("@redis/json/dist/commands/MERGE");
|
||||
merge: typeof import("@redis/json/dist/commands/MERGE");
|
||||
MGET: typeof import("@redis/json/dist/commands/MGET");
|
||||
mGet: typeof import("@redis/json/dist/commands/MGET");
|
||||
MSET: typeof import("@redis/json/dist/commands/MSET");
|
||||
mSet: typeof import("@redis/json/dist/commands/MSET");
|
||||
NUMINCRBY: typeof import("@redis/json/dist/commands/NUMINCRBY");
|
||||
numIncrBy: typeof import("@redis/json/dist/commands/NUMINCRBY");
|
||||
NUMMULTBY: typeof import("@redis/json/dist/commands/NUMMULTBY");
|
||||
numMultBy: typeof import("@redis/json/dist/commands/NUMMULTBY");
|
||||
OBJKEYS: typeof import("@redis/json/dist/commands/OBJKEYS");
|
||||
objKeys: typeof import("@redis/json/dist/commands/OBJKEYS");
|
||||
OBJLEN: typeof import("@redis/json/dist/commands/OBJLEN");
|
||||
objLen: typeof import("@redis/json/dist/commands/OBJLEN");
|
||||
RESP: typeof import("@redis/json/dist/commands/RESP");
|
||||
resp: typeof import("@redis/json/dist/commands/RESP");
|
||||
SET: typeof import("@redis/json/dist/commands/SET");
|
||||
set: typeof import("@redis/json/dist/commands/SET");
|
||||
STRAPPEND: typeof import("@redis/json/dist/commands/STRAPPEND");
|
||||
strAppend: typeof import("@redis/json/dist/commands/STRAPPEND");
|
||||
STRLEN: typeof import("@redis/json/dist/commands/STRLEN");
|
||||
strLen: typeof import("@redis/json/dist/commands/STRLEN");
|
||||
TYPE: typeof import("@redis/json/dist/commands/TYPE");
|
||||
type: typeof import("@redis/json/dist/commands/TYPE");
|
||||
};
|
||||
ft: {
|
||||
_LIST: typeof import("@redis/search/dist/commands/_LIST");
|
||||
_list: typeof import("@redis/search/dist/commands/_LIST");
|
||||
ALTER: typeof import("@redis/search/dist/commands/ALTER");
|
||||
alter: typeof import("@redis/search/dist/commands/ALTER");
|
||||
AGGREGATE_WITHCURSOR: typeof import("@redis/search/dist/commands/AGGREGATE_WITHCURSOR");
|
||||
aggregateWithCursor: typeof import("@redis/search/dist/commands/AGGREGATE_WITHCURSOR");
|
||||
AGGREGATE: typeof import("@redis/search/dist/commands/AGGREGATE");
|
||||
aggregate: typeof import("@redis/search/dist/commands/AGGREGATE");
|
||||
ALIASADD: typeof import("@redis/search/dist/commands/ALIASADD");
|
||||
aliasAdd: typeof import("@redis/search/dist/commands/ALIASADD");
|
||||
ALIASDEL: typeof import("@redis/search/dist/commands/ALIASDEL");
|
||||
aliasDel: typeof import("@redis/search/dist/commands/ALIASDEL");
|
||||
ALIASUPDATE: typeof import("@redis/search/dist/commands/ALIASUPDATE");
|
||||
aliasUpdate: typeof import("@redis/search/dist/commands/ALIASUPDATE");
|
||||
CONFIG_GET: typeof import("@redis/search/dist/commands/CONFIG_GET");
|
||||
configGet: typeof import("@redis/search/dist/commands/CONFIG_GET");
|
||||
CONFIG_SET: typeof import("@redis/search/dist/commands/CONFIG_SET");
|
||||
configSet: typeof import("@redis/search/dist/commands/CONFIG_SET");
|
||||
CREATE: typeof import("@redis/search/dist/commands/CREATE");
|
||||
create: typeof import("@redis/search/dist/commands/CREATE");
|
||||
CURSOR_DEL: typeof import("@redis/search/dist/commands/CURSOR_DEL");
|
||||
cursorDel: typeof import("@redis/search/dist/commands/CURSOR_DEL");
|
||||
CURSOR_READ: typeof import("@redis/search/dist/commands/CURSOR_READ");
|
||||
cursorRead: typeof import("@redis/search/dist/commands/CURSOR_READ");
|
||||
DICTADD: typeof import("@redis/search/dist/commands/DICTADD");
|
||||
dictAdd: typeof import("@redis/search/dist/commands/DICTADD");
|
||||
DICTDEL: typeof import("@redis/search/dist/commands/DICTDEL");
|
||||
dictDel: typeof import("@redis/search/dist/commands/DICTDEL");
|
||||
DICTDUMP: typeof import("@redis/search/dist/commands/DICTDUMP");
|
||||
dictDump: typeof import("@redis/search/dist/commands/DICTDUMP");
|
||||
DROPINDEX: typeof import("@redis/search/dist/commands/DROPINDEX");
|
||||
dropIndex: typeof import("@redis/search/dist/commands/DROPINDEX");
|
||||
EXPLAIN: typeof import("@redis/search/dist/commands/EXPLAIN");
|
||||
explain: typeof import("@redis/search/dist/commands/EXPLAIN");
|
||||
EXPLAINCLI: typeof import("@redis/search/dist/commands/EXPLAINCLI");
|
||||
explainCli: typeof import("@redis/search/dist/commands/EXPLAINCLI");
|
||||
INFO: typeof import("@redis/search/dist/commands/INFO");
|
||||
info: typeof import("@redis/search/dist/commands/INFO");
|
||||
PROFILESEARCH: typeof import("@redis/search/dist/commands/PROFILE_SEARCH");
|
||||
profileSearch: typeof import("@redis/search/dist/commands/PROFILE_SEARCH");
|
||||
PROFILEAGGREGATE: typeof import("@redis/search/dist/commands/PROFILE_AGGREGATE");
|
||||
profileAggregate: typeof import("@redis/search/dist/commands/PROFILE_AGGREGATE");
|
||||
SEARCH: typeof import("@redis/search/dist/commands/SEARCH");
|
||||
search: typeof import("@redis/search/dist/commands/SEARCH");
|
||||
SEARCH_NOCONTENT: typeof import("@redis/search/dist/commands/SEARCH_NOCONTENT");
|
||||
searchNoContent: typeof import("@redis/search/dist/commands/SEARCH_NOCONTENT");
|
||||
SPELLCHECK: typeof import("@redis/search/dist/commands/SPELLCHECK");
|
||||
spellCheck: typeof import("@redis/search/dist/commands/SPELLCHECK");
|
||||
SUGADD: typeof import("@redis/search/dist/commands/SUGADD");
|
||||
sugAdd: typeof import("@redis/search/dist/commands/SUGADD");
|
||||
SUGDEL: typeof import("@redis/search/dist/commands/SUGDEL");
|
||||
sugDel: typeof import("@redis/search/dist/commands/SUGDEL");
|
||||
SUGGET_WITHPAYLOADS: typeof import("@redis/search/dist/commands/SUGGET_WITHPAYLOADS");
|
||||
sugGetWithPayloads: typeof import("@redis/search/dist/commands/SUGGET_WITHPAYLOADS");
|
||||
SUGGET_WITHSCORES_WITHPAYLOADS: typeof import("@redis/search/dist/commands/SUGGET_WITHSCORES_WITHPAYLOADS");
|
||||
sugGetWithScoresWithPayloads: typeof import("@redis/search/dist/commands/SUGGET_WITHSCORES_WITHPAYLOADS");
|
||||
SUGGET_WITHSCORES: typeof import("@redis/search/dist/commands/SUGGET_WITHSCORES");
|
||||
sugGetWithScores: typeof import("@redis/search/dist/commands/SUGGET_WITHSCORES");
|
||||
SUGGET: typeof import("@redis/search/dist/commands/SUGGET");
|
||||
sugGet: typeof import("@redis/search/dist/commands/SUGGET");
|
||||
SUGLEN: typeof import("@redis/search/dist/commands/SUGLEN");
|
||||
sugLen: typeof import("@redis/search/dist/commands/SUGLEN");
|
||||
SYNDUMP: typeof import("@redis/search/dist/commands/SYNDUMP");
|
||||
synDump: typeof import("@redis/search/dist/commands/SYNDUMP");
|
||||
SYNUPDATE: typeof import("@redis/search/dist/commands/SYNUPDATE");
|
||||
synUpdate: typeof import("@redis/search/dist/commands/SYNUPDATE");
|
||||
TAGVALS: typeof import("@redis/search/dist/commands/TAGVALS");
|
||||
tagVals: typeof import("@redis/search/dist/commands/TAGVALS");
|
||||
};
|
||||
ts: {
|
||||
ADD: typeof import("@redis/time-series/dist/commands/ADD");
|
||||
add: typeof import("@redis/time-series/dist/commands/ADD");
|
||||
ALTER: typeof import("@redis/time-series/dist/commands/ALTER");
|
||||
alter: typeof import("@redis/time-series/dist/commands/ALTER");
|
||||
CREATE: typeof import("@redis/time-series/dist/commands/CREATE");
|
||||
create: typeof import("@redis/time-series/dist/commands/CREATE");
|
||||
CREATERULE: typeof import("@redis/time-series/dist/commands/CREATERULE");
|
||||
createRule: typeof import("@redis/time-series/dist/commands/CREATERULE");
|
||||
DECRBY: typeof import("@redis/time-series/dist/commands/DECRBY");
|
||||
decrBy: typeof import("@redis/time-series/dist/commands/DECRBY");
|
||||
DEL: typeof import("@redis/time-series/dist/commands/DEL");
|
||||
del: typeof import("@redis/time-series/dist/commands/DEL");
|
||||
DELETERULE: typeof import("@redis/time-series/dist/commands/DELETERULE");
|
||||
deleteRule: typeof import("@redis/time-series/dist/commands/DELETERULE");
|
||||
GET: typeof import("@redis/time-series/dist/commands/GET");
|
||||
get: typeof import("@redis/time-series/dist/commands/GET");
|
||||
INCRBY: typeof import("@redis/time-series/dist/commands/INCRBY");
|
||||
incrBy: typeof import("@redis/time-series/dist/commands/INCRBY");
|
||||
INFO_DEBUG: typeof import("@redis/time-series/dist/commands/INFO_DEBUG");
|
||||
infoDebug: typeof import("@redis/time-series/dist/commands/INFO_DEBUG");
|
||||
INFO: typeof import("@redis/time-series/dist/commands/INFO");
|
||||
info: typeof import("@redis/time-series/dist/commands/INFO");
|
||||
MADD: typeof import("@redis/time-series/dist/commands/MADD");
|
||||
mAdd: typeof import("@redis/time-series/dist/commands/MADD");
|
||||
MGET: typeof import("@redis/time-series/dist/commands/MGET");
|
||||
mGet: typeof import("@redis/time-series/dist/commands/MGET");
|
||||
MGET_WITHLABELS: typeof import("@redis/time-series/dist/commands/MGET_WITHLABELS");
|
||||
mGetWithLabels: typeof import("@redis/time-series/dist/commands/MGET_WITHLABELS");
|
||||
QUERYINDEX: typeof import("@redis/time-series/dist/commands/QUERYINDEX");
|
||||
queryIndex: typeof import("@redis/time-series/dist/commands/QUERYINDEX");
|
||||
RANGE: typeof import("@redis/time-series/dist/commands/RANGE");
|
||||
range: typeof import("@redis/time-series/dist/commands/RANGE");
|
||||
REVRANGE: typeof import("@redis/time-series/dist/commands/REVRANGE");
|
||||
revRange: typeof import("@redis/time-series/dist/commands/REVRANGE");
|
||||
MRANGE: typeof import("@redis/time-series/dist/commands/MRANGE");
|
||||
mRange: typeof import("@redis/time-series/dist/commands/MRANGE");
|
||||
MRANGE_WITHLABELS: typeof import("@redis/time-series/dist/commands/MRANGE_WITHLABELS");
|
||||
mRangeWithLabels: typeof import("@redis/time-series/dist/commands/MRANGE_WITHLABELS");
|
||||
MREVRANGE: typeof import("@redis/time-series/dist/commands/MREVRANGE");
|
||||
mRevRange: typeof import("@redis/time-series/dist/commands/MREVRANGE");
|
||||
MREVRANGE_WITHLABELS: typeof import("@redis/time-series/dist/commands/MREVRANGE_WITHLABELS");
|
||||
mRevRangeWithLabels: typeof import("@redis/time-series/dist/commands/MREVRANGE_WITHLABELS");
|
||||
};
|
||||
bf: {
|
||||
ADD: typeof import("@redis/bloom/dist/commands/bloom/ADD");
|
||||
add: typeof import("@redis/bloom/dist/commands/bloom/ADD");
|
||||
CARD: typeof import("@redis/bloom/dist/commands/bloom/CARD");
|
||||
card: typeof import("@redis/bloom/dist/commands/bloom/CARD");
|
||||
EXISTS: typeof import("@redis/bloom/dist/commands/bloom/EXISTS");
|
||||
exists: typeof import("@redis/bloom/dist/commands/bloom/EXISTS");
|
||||
INFO: typeof import("@redis/bloom/dist/commands/bloom/INFO");
|
||||
info: typeof import("@redis/bloom/dist/commands/bloom/INFO");
|
||||
INSERT: typeof import("@redis/bloom/dist/commands/bloom/INSERT");
|
||||
insert: typeof import("@redis/bloom/dist/commands/bloom/INSERT");
|
||||
LOADCHUNK: typeof import("@redis/bloom/dist/commands/bloom/LOADCHUNK");
|
||||
loadChunk: typeof import("@redis/bloom/dist/commands/bloom/LOADCHUNK");
|
||||
MADD: typeof import("@redis/bloom/dist/commands/bloom/MADD");
|
||||
mAdd: typeof import("@redis/bloom/dist/commands/bloom/MADD");
|
||||
MEXISTS: typeof import("@redis/bloom/dist/commands/bloom/MEXISTS");
|
||||
mExists: typeof import("@redis/bloom/dist/commands/bloom/MEXISTS");
|
||||
RESERVE: typeof import("@redis/bloom/dist/commands/bloom/RESERVE");
|
||||
reserve: typeof import("@redis/bloom/dist/commands/bloom/RESERVE");
|
||||
SCANDUMP: typeof import("@redis/bloom/dist/commands/bloom/SCANDUMP");
|
||||
scanDump: typeof import("@redis/bloom/dist/commands/bloom/SCANDUMP");
|
||||
};
|
||||
cms: {
|
||||
INCRBY: typeof import("@redis/bloom/dist/commands/count-min-sketch/INCRBY");
|
||||
incrBy: typeof import("@redis/bloom/dist/commands/count-min-sketch/INCRBY");
|
||||
INFO: typeof import("@redis/bloom/dist/commands/count-min-sketch/INFO");
|
||||
info: typeof import("@redis/bloom/dist/commands/count-min-sketch/INFO");
|
||||
INITBYDIM: typeof import("@redis/bloom/dist/commands/count-min-sketch/INITBYDIM");
|
||||
initByDim: typeof import("@redis/bloom/dist/commands/count-min-sketch/INITBYDIM");
|
||||
INITBYPROB: typeof import("@redis/bloom/dist/commands/count-min-sketch/INITBYPROB");
|
||||
initByProb: typeof import("@redis/bloom/dist/commands/count-min-sketch/INITBYPROB");
|
||||
MERGE: typeof import("@redis/bloom/dist/commands/count-min-sketch/MERGE");
|
||||
merge: typeof import("@redis/bloom/dist/commands/count-min-sketch/MERGE");
|
||||
QUERY: typeof import("@redis/bloom/dist/commands/count-min-sketch/QUERY");
|
||||
query: typeof import("@redis/bloom/dist/commands/count-min-sketch/QUERY");
|
||||
};
|
||||
cf: {
|
||||
ADD: typeof import("@redis/bloom/dist/commands/cuckoo/ADD");
|
||||
add: typeof import("@redis/bloom/dist/commands/cuckoo/ADD");
|
||||
ADDNX: typeof import("@redis/bloom/dist/commands/cuckoo/ADDNX");
|
||||
addNX: typeof import("@redis/bloom/dist/commands/cuckoo/ADDNX");
|
||||
COUNT: typeof import("@redis/bloom/dist/commands/cuckoo/COUNT");
|
||||
count: typeof import("@redis/bloom/dist/commands/cuckoo/COUNT");
|
||||
DEL: typeof import("@redis/bloom/dist/commands/cuckoo/DEL");
|
||||
del: typeof import("@redis/bloom/dist/commands/cuckoo/DEL");
|
||||
EXISTS: typeof import("@redis/bloom/dist/commands/cuckoo/EXISTS");
|
||||
exists: typeof import("@redis/bloom/dist/commands/cuckoo/EXISTS");
|
||||
INFO: typeof import("@redis/bloom/dist/commands/cuckoo/INFO");
|
||||
info: typeof import("@redis/bloom/dist/commands/cuckoo/INFO");
|
||||
INSERT: typeof import("@redis/bloom/dist/commands/cuckoo/INSERT");
|
||||
insert: typeof import("@redis/bloom/dist/commands/cuckoo/INSERT");
|
||||
INSERTNX: typeof import("@redis/bloom/dist/commands/cuckoo/INSERTNX");
|
||||
insertNX: typeof import("@redis/bloom/dist/commands/cuckoo/INSERTNX");
|
||||
LOADCHUNK: typeof import("@redis/bloom/dist/commands/cuckoo/LOADCHUNK");
|
||||
loadChunk: typeof import("@redis/bloom/dist/commands/cuckoo/LOADCHUNK");
|
||||
RESERVE: typeof import("@redis/bloom/dist/commands/cuckoo/RESERVE");
|
||||
reserve: typeof import("@redis/bloom/dist/commands/cuckoo/RESERVE");
|
||||
SCANDUMP: typeof import("@redis/bloom/dist/commands/cuckoo/SCANDUMP");
|
||||
scanDump: typeof import("@redis/bloom/dist/commands/cuckoo/SCANDUMP");
|
||||
};
|
||||
tDigest: {
|
||||
ADD: typeof import("@redis/bloom/dist/commands/t-digest/ADD");
|
||||
add: typeof import("@redis/bloom/dist/commands/t-digest/ADD");
|
||||
BYRANK: typeof import("@redis/bloom/dist/commands/t-digest/BYRANK");
|
||||
byRank: typeof import("@redis/bloom/dist/commands/t-digest/BYRANK");
|
||||
BYREVRANK: typeof import("@redis/bloom/dist/commands/t-digest/BYREVRANK");
|
||||
byRevRank: typeof import("@redis/bloom/dist/commands/t-digest/BYREVRANK");
|
||||
CDF: typeof import("@redis/bloom/dist/commands/t-digest/CDF");
|
||||
cdf: typeof import("@redis/bloom/dist/commands/t-digest/CDF");
|
||||
CREATE: typeof import("@redis/bloom/dist/commands/t-digest/CREATE");
|
||||
create: typeof import("@redis/bloom/dist/commands/t-digest/CREATE");
|
||||
INFO: typeof import("@redis/bloom/dist/commands/t-digest/INFO");
|
||||
info: typeof import("@redis/bloom/dist/commands/t-digest/INFO");
|
||||
MAX: typeof import("@redis/bloom/dist/commands/t-digest/MAX");
|
||||
max: typeof import("@redis/bloom/dist/commands/t-digest/MAX");
|
||||
MERGE: typeof import("@redis/bloom/dist/commands/t-digest/MERGE");
|
||||
merge: typeof import("@redis/bloom/dist/commands/t-digest/MERGE");
|
||||
MIN: typeof import("@redis/bloom/dist/commands/t-digest/MIN");
|
||||
min: typeof import("@redis/bloom/dist/commands/t-digest/MIN");
|
||||
QUANTILE: typeof import("@redis/bloom/dist/commands/t-digest/QUANTILE");
|
||||
quantile: typeof import("@redis/bloom/dist/commands/t-digest/QUANTILE");
|
||||
RANK: typeof import("@redis/bloom/dist/commands/t-digest/RANK");
|
||||
rank: typeof import("@redis/bloom/dist/commands/t-digest/RANK");
|
||||
RESET: typeof import("@redis/bloom/dist/commands/t-digest/RESET");
|
||||
reset: typeof import("@redis/bloom/dist/commands/t-digest/RESET");
|
||||
REVRANK: typeof import("@redis/bloom/dist/commands/t-digest/REVRANK");
|
||||
revRank: typeof import("@redis/bloom/dist/commands/t-digest/REVRANK");
|
||||
TRIMMED_MEAN: typeof import("@redis/bloom/dist/commands/t-digest/TRIMMED_MEAN");
|
||||
trimmedMean: typeof import("@redis/bloom/dist/commands/t-digest/TRIMMED_MEAN");
|
||||
};
|
||||
topK: {
|
||||
ADD: typeof import("@redis/bloom/dist/commands/top-k/ADD");
|
||||
add: typeof import("@redis/bloom/dist/commands/top-k/ADD");
|
||||
COUNT: typeof import("@redis/bloom/dist/commands/top-k/COUNT");
|
||||
count: typeof import("@redis/bloom/dist/commands/top-k/COUNT");
|
||||
INCRBY: typeof import("@redis/bloom/dist/commands/top-k/INCRBY");
|
||||
incrBy: typeof import("@redis/bloom/dist/commands/top-k/INCRBY");
|
||||
INFO: typeof import("@redis/bloom/dist/commands/top-k/INFO");
|
||||
info: typeof import("@redis/bloom/dist/commands/top-k/INFO");
|
||||
LIST_WITHCOUNT: typeof import("@redis/bloom/dist/commands/top-k/LIST_WITHCOUNT");
|
||||
listWithCount: typeof import("@redis/bloom/dist/commands/top-k/LIST_WITHCOUNT");
|
||||
LIST: typeof import("@redis/bloom/dist/commands/top-k/LIST");
|
||||
list: typeof import("@redis/bloom/dist/commands/top-k/LIST");
|
||||
QUERY: typeof import("@redis/bloom/dist/commands/top-k/QUERY");
|
||||
query: typeof import("@redis/bloom/dist/commands/top-k/QUERY");
|
||||
RESERVE: typeof import("@redis/bloom/dist/commands/top-k/RESERVE");
|
||||
reserve: typeof import("@redis/bloom/dist/commands/top-k/RESERVE");
|
||||
};
|
||||
} & import("redis").RedisModules, import("redis").RedisFunctions, import("redis").RedisScripts>;
|
||||
export default redisClient;
|
||||
//# sourceMappingURL=redis.d.ts.map
|
||||
1
backend-old-20260125/dist/config/redis.d.ts.map
vendored
Normal file
1
backend-old-20260125/dist/config/redis.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"redis.d.ts","sourceRoot":"","sources":["../../src/config/redis.ts"],"names":[],"mappings":"AAKA,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+FAEf,CAAC;AAeH,eAAe,WAAW,CAAC"}
|
||||
23
backend-old-20260125/dist/config/redis.js
vendored
Normal file
23
backend-old-20260125/dist/config/redis.js
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const redis_1 = require("redis");
|
||||
const dotenv_1 = __importDefault(require("dotenv"));
|
||||
dotenv_1.default.config();
|
||||
const redisClient = (0, redis_1.createClient)({
|
||||
url: process.env.REDIS_URL || 'redis://localhost:6379'
|
||||
});
|
||||
redisClient.on('connect', () => {
|
||||
console.log('✅ Connected to Redis');
|
||||
});
|
||||
redisClient.on('error', (err) => {
|
||||
console.error('❌ Redis connection error:', err);
|
||||
});
|
||||
// Connect to Redis
|
||||
redisClient.connect().catch((err) => {
|
||||
console.error('❌ Failed to connect to Redis:', err);
|
||||
});
|
||||
exports.default = redisClient;
|
||||
//# sourceMappingURL=redis.js.map
|
||||
1
backend-old-20260125/dist/config/redis.js.map
vendored
Normal file
1
backend-old-20260125/dist/config/redis.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"redis.js","sourceRoot":"","sources":["../../src/config/redis.ts"],"names":[],"mappings":";;;;;AAAA,iCAAqC;AACrC,oDAA4B;AAE5B,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,MAAM,WAAW,GAAG,IAAA,oBAAY,EAAC;IAC/B,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,wBAAwB;CACvD,CAAC,CAAC;AAEH,WAAW,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IAC7B,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACtC,CAAC,CAAC,CAAC;AAEH,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAU,EAAE,EAAE;IACrC,OAAO,CAAC,KAAK,CAAC,2BAA2B,EAAE,GAAG,CAAC,CAAC;AAClD,CAAC,CAAC,CAAC;AAEH,mBAAmB;AACnB,WAAW,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;IACzC,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC;AAEH,kBAAe,WAAW,CAAC"}
|
||||
9
backend-old-20260125/dist/config/simpleAuth.d.ts
vendored
Normal file
9
backend-old-20260125/dist/config/simpleAuth.d.ts
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import { User } from '../services/jwtKeyManager';
|
||||
export { User } from '../services/jwtKeyManager';
|
||||
export declare function generateToken(user: User): string;
|
||||
export declare function verifyToken(token: string): User | null;
|
||||
export declare function verifyGoogleToken(googleToken: string): Promise<any>;
|
||||
export declare function getGoogleAuthUrl(): string;
|
||||
export declare function exchangeCodeForTokens(code: string): Promise<any>;
|
||||
export declare function getGoogleUserInfo(accessToken: string): Promise<any>;
|
||||
//# sourceMappingURL=simpleAuth.d.ts.map
|
||||
1
backend-old-20260125/dist/config/simpleAuth.d.ts.map
vendored
Normal file
1
backend-old-20260125/dist/config/simpleAuth.d.ts.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"simpleAuth.d.ts","sourceRoot":"","sources":["../../src/config/simpleAuth.ts"],"names":[],"mappings":"AAAA,OAAsB,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAKhE,OAAO,EAAE,IAAI,EAAE,MAAM,2BAA2B,CAAC;AAEjD,wBAAgB,aAAa,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAEhD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAEtD;AAGD,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAWzE;AAGD,wBAAgB,gBAAgB,IAAI,MAAM,CAiCzC;AAGD,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAgGtE;AAGD,wBAAsB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAsEzE"}
|
||||
217
backend-old-20260125/dist/config/simpleAuth.js
vendored
Normal file
217
backend-old-20260125/dist/config/simpleAuth.js
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.User = void 0;
|
||||
exports.generateToken = generateToken;
|
||||
exports.verifyToken = verifyToken;
|
||||
exports.verifyGoogleToken = verifyGoogleToken;
|
||||
exports.getGoogleAuthUrl = getGoogleAuthUrl;
|
||||
exports.exchangeCodeForTokens = exchangeCodeForTokens;
|
||||
exports.getGoogleUserInfo = getGoogleUserInfo;
|
||||
const jwtKeyManager_1 = __importDefault(require("../services/jwtKeyManager"));
|
||||
// JWT Key Manager now handles all token operations with automatic rotation
|
||||
// No more static JWT_SECRET needed!
|
||||
var jwtKeyManager_2 = require("../services/jwtKeyManager");
|
||||
Object.defineProperty(exports, "User", { enumerable: true, get: function () { return jwtKeyManager_2.User; } });
|
||||
function generateToken(user) {
|
||||
return jwtKeyManager_1.default.generateToken(user);
|
||||
}
|
||||
function verifyToken(token) {
|
||||
return jwtKeyManager_1.default.verifyToken(token);
|
||||
}
|
||||
// Simple Google OAuth2 client using fetch
|
||||
async function verifyGoogleToken(googleToken) {
|
||||
try {
|
||||
const response = await fetch(`https://www.googleapis.com/oauth2/v1/userinfo?access_token=${googleToken}`);
|
||||
if (!response.ok) {
|
||||
throw new Error('Invalid Google token');
|
||||
}
|
||||
return await response.json();
|
||||
}
|
||||
catch (error) {
|
||||
console.error('Error verifying Google token:', error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
// Get Google OAuth2 URL
|
||||
function getGoogleAuthUrl() {
|
||||
const clientId = process.env.GOOGLE_CLIENT_ID;
|
||||
const redirectUri = process.env.GOOGLE_REDIRECT_URI || 'http://localhost:3000/auth/google/callback';
|
||||
console.log('🔗 Generating Google OAuth URL:', {
|
||||
client_id_present: !!clientId,
|
||||
redirect_uri: redirectUri,
|
||||
environment: process.env.NODE_ENV || 'development'
|
||||
});
|
||||
if (!clientId) {
|
||||
console.error('❌ GOOGLE_CLIENT_ID not configured');
|
||||
throw new Error('GOOGLE_CLIENT_ID not configured');
|
||||
}
|
||||
if (!redirectUri.startsWith('http')) {
|
||||
console.error('❌ Invalid redirect URI:', redirectUri);
|
||||
throw new Error('GOOGLE_REDIRECT_URI must be a valid HTTP/HTTPS URL');
|
||||
}
|
||||
const params = new URLSearchParams({
|
||||
client_id: clientId,
|
||||
redirect_uri: redirectUri,
|
||||
response_type: 'code',
|
||||
scope: 'openid email profile',
|
||||
access_type: 'offline',
|
||||
prompt: 'consent'
|
||||
});
|
||||
const authUrl = `https://accounts.google.com/o/oauth2/v2/auth?${params.toString()}`;
|
||||
console.log('✅ Google OAuth URL generated successfully');
|
||||
return authUrl;
|
||||
}
|
||||
// Exchange authorization code for tokens
|
||||
async function exchangeCodeForTokens(code) {
|
||||
const clientId = process.env.GOOGLE_CLIENT_ID;
|
||||
const clientSecret = process.env.GOOGLE_CLIENT_SECRET;
|
||||
const redirectUri = process.env.GOOGLE_REDIRECT_URI || 'http://localhost:3000/auth/google/callback';
|
||||
console.log('🔄 Exchanging OAuth code for tokens:', {
|
||||
client_id_present: !!clientId,
|
||||
client_secret_present: !!clientSecret,
|
||||
redirect_uri: redirectUri,
|
||||
code_length: code?.length || 0
|
||||
});
|
||||
if (!clientId || !clientSecret) {
|
||||
console.error('❌ Google OAuth credentials not configured:', {
|
||||
client_id: !!clientId,
|
||||
client_secret: !!clientSecret
|
||||
});
|
||||
throw new Error('Google OAuth credentials not configured');
|
||||
}
|
||||
if (!code || code.length < 10) {
|
||||
console.error('❌ Invalid authorization code:', { code_length: code?.length || 0 });
|
||||
throw new Error('Invalid authorization code provided');
|
||||
}
|
||||
try {
|
||||
const tokenUrl = 'https://oauth2.googleapis.com/token';
|
||||
const requestBody = new URLSearchParams({
|
||||
client_id: clientId,
|
||||
client_secret: clientSecret,
|
||||
code,
|
||||
grant_type: 'authorization_code',
|
||||
redirect_uri: redirectUri,
|
||||
});
|
||||
console.log('📡 Making token exchange request to Google:', {
|
||||
url: tokenUrl,
|
||||
redirect_uri: redirectUri,
|
||||
grant_type: 'authorization_code'
|
||||
});
|
||||
const response = await fetch(tokenUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
'Accept': 'application/json'
|
||||
},
|
||||
body: requestBody,
|
||||
});
|
||||
const responseText = await response.text();
|
||||
console.log('📨 Token exchange response:', {
|
||||
status: response.status,
|
||||
ok: response.ok,
|
||||
content_type: response.headers.get('content-type'),
|
||||
response_length: responseText.length
|
||||
});
|
||||
if (!response.ok) {
|
||||
console.error('❌ Token exchange failed:', {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
response: responseText
|
||||
});
|
||||
throw new Error(`Failed to exchange code for tokens: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
let tokenData;
|
||||
try {
|
||||
tokenData = JSON.parse(responseText);
|
||||
}
|
||||
catch (parseError) {
|
||||
console.error('❌ Failed to parse token response:', { response: responseText });
|
||||
throw new Error('Invalid JSON response from Google token endpoint');
|
||||
}
|
||||
if (!tokenData.access_token) {
|
||||
console.error('❌ No access token in response:', tokenData);
|
||||
throw new Error('No access token received from Google');
|
||||
}
|
||||
console.log('✅ Token exchange successful:', {
|
||||
has_access_token: !!tokenData.access_token,
|
||||
has_refresh_token: !!tokenData.refresh_token,
|
||||
token_type: tokenData.token_type,
|
||||
expires_in: tokenData.expires_in
|
||||
});
|
||||
return tokenData;
|
||||
}
|
||||
catch (error) {
|
||||
console.error('❌ Error exchanging code for tokens:', {
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
stack: error instanceof Error ? error.stack : undefined
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
// Get user info from Google
|
||||
async function getGoogleUserInfo(accessToken) {
|
||||
console.log('👤 Getting user info from Google:', {
|
||||
token_length: accessToken?.length || 0,
|
||||
token_prefix: accessToken ? accessToken.substring(0, 10) + '...' : 'none'
|
||||
});
|
||||
if (!accessToken || accessToken.length < 10) {
|
||||
console.error('❌ Invalid access token for user info request');
|
||||
throw new Error('Invalid access token provided');
|
||||
}
|
||||
try {
|
||||
const userInfoUrl = `https://www.googleapis.com/oauth2/v2/userinfo?access_token=${accessToken}`;
|
||||
console.log('📡 Making user info request to Google');
|
||||
const response = await fetch(userInfoUrl, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Accept': 'application/json',
|
||||
'Authorization': `Bearer ${accessToken}`
|
||||
}
|
||||
});
|
||||
const responseText = await response.text();
|
||||
console.log('📨 User info response:', {
|
||||
status: response.status,
|
||||
ok: response.ok,
|
||||
content_type: response.headers.get('content-type'),
|
||||
response_length: responseText.length
|
||||
});
|
||||
if (!response.ok) {
|
||||
console.error('❌ Failed to get user info:', {
|
||||
status: response.status,
|
||||
statusText: response.statusText,
|
||||
response: responseText
|
||||
});
|
||||
throw new Error(`Failed to get user info: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
let userData;
|
||||
try {
|
||||
userData = JSON.parse(responseText);
|
||||
}
|
||||
catch (parseError) {
|
||||
console.error('❌ Failed to parse user info response:', { response: responseText });
|
||||
throw new Error('Invalid JSON response from Google user info endpoint');
|
||||
}
|
||||
if (!userData.email) {
|
||||
console.error('❌ No email in user info response:', userData);
|
||||
throw new Error('No email address received from Google');
|
||||
}
|
||||
console.log('✅ User info retrieved successfully:', {
|
||||
email: userData.email,
|
||||
name: userData.name,
|
||||
verified_email: userData.verified_email,
|
||||
has_picture: !!userData.picture
|
||||
});
|
||||
return userData;
|
||||
}
|
||||
catch (error) {
|
||||
console.error('❌ Error getting Google user info:', {
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
stack: error instanceof Error ? error.stack : undefined
|
||||
});
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=simpleAuth.js.map
|
||||
1
backend-old-20260125/dist/config/simpleAuth.js.map
vendored
Normal file
1
backend-old-20260125/dist/config/simpleAuth.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user