admin08077 commited on
Commit
885dabb
·
verified ·
1 Parent(s): 89261a7

Update server.js

Browse files
Files changed (1) hide show
  1. server.js +64 -154
server.js CHANGED
@@ -1,13 +1,11 @@
1
  import express from 'express';
2
  import cors from 'cors';
3
- import { GoogleGenAI } from '@google/genai';
4
  import path from 'path';
5
  import { fileURLToPath } from 'url';
6
  import sqlite3 from 'sqlite3';
7
  import bcrypt from 'bcryptjs';
8
 
9
  const app = express();
10
- // Hugging Face Spaces require port 7860
11
  const port = process.env.PORT || 7860;
12
 
13
  // --- Database Initialization ---
@@ -17,7 +15,6 @@ const dbPath = path.join(__dirname, 'database.db');
17
  const db = new sqlite3.Database(dbPath);
18
 
19
  db.serialize(() => {
20
- // Users table
21
  db.run(`
22
  CREATE TABLE IF NOT EXISTS users (
23
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -27,8 +24,6 @@ db.serialize(() => {
27
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
28
  )
29
  `);
30
-
31
- // Messages table for Neural Memory
32
  db.run(`
33
  CREATE TABLE IF NOT EXISTS messages (
34
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -41,188 +36,103 @@ db.serialize(() => {
41
  `);
42
  });
43
 
44
- // --- Simulated In-Memory Session Storage ---
45
  let activeSession = null;
46
 
47
- // --- Mock Citi Financial Data ---
48
  const CITI_ACCOUNTS = {
49
- accountGroupDetails: [
50
- {
51
- accountGroup: "CHECKING",
52
- checkingAccountsDetails: [
53
- {
54
- productName: "Corporate Mastery Checking",
55
- accountNickname: "Main Ops Node",
56
- accountDescription: "Corporate Mastery Checking - 9594",
57
- balanceType: "ASSET",
58
- displayAccountNumber: "XXXXXX9594",
59
- accountId: "citi_acc_99201",
60
- currencyCode: "USD",
61
- accountStatus: "ACTIVE",
62
- currentBalance: 1245000.50,
63
- availableBalance: 1240000.00
64
- }
65
- ],
66
- totalCurrentBalance: { localCurrencyCode: "USD", localCurrencyBalanceAmount: 1245000.50 },
67
- totalAvailableBalance: { localCurrencyCode: "USD", localCurrencyBalanceAmount: 1240000.00 }
68
- }
69
- ],
70
- customer: {
71
- customerId: "citi_cust_884102"
72
- }
73
- };
74
-
75
- const CITI_TRANSACTIONS = {
76
- "citi_acc_99201": {
77
- checkingAccountTransactions: [
78
- {
79
- accountId: "citi_acc_99201",
80
- currencyCode: "USD",
81
- transactionAmount: -25000.00,
82
- transactionDate: "2024-03-31",
83
- transactionDescription: "NEURAL_NETWORK_COMPUTE_Q1_ALLOCATION",
84
- transactionId: "TXN_C_884102",
85
- transactionStatus: "POSTED",
86
- transactionType: "PAYMENT",
87
- displayAccountNumber: "XXXXXX9594"
88
- }
89
- ]
90
- }
91
  };
92
 
93
  app.use(cors());
94
  app.use(express.json());
95
  app.use(express.urlencoded({ extended: true }));
96
 
97
- // --- Authentication Endpoints ---
98
-
99
- app.get('/api/auth/me', (req, res) => {
100
- if (activeSession) {
101
- res.json({ isAuthenticated: true, user: activeSession });
102
- } else {
103
- res.status(401).json({ isAuthenticated: false, user: null });
104
- }
105
- });
106
-
107
- app.post('/api/auth/register', async (req, res) => {
108
- const { username, password } = req.body;
109
- if (!username || !password) return res.status(400).json({ error: 'Identity credentials missing.' });
110
-
111
- try {
112
- const hash = await bcrypt.hash(password, 10);
113
- db.run(
114
- 'INSERT INTO users (username, password_hash, role) VALUES (?, ?, ?)',
115
- [username, hash, 'Root Admin'],
116
- function(err) {
117
- if (err) {
118
- if (err.message.includes('UNIQUE')) {
119
- return res.status(409).json({ error: 'Identity node already registered.' });
120
- }
121
- return res.status(500).json({ error: 'Registry write failure.' });
122
- }
123
- res.status(201).json({ success: true, userId: this.lastID });
124
- }
125
- );
126
- } catch (error) {
127
- res.status(500).json({ error: 'Encryption engine failure.' });
128
- }
129
- });
130
-
131
  app.post('/api/auth/login', (req, res) => {
132
  const { username, password } = req.body;
133
-
134
  db.get('SELECT * FROM users WHERE username = ?', [username], async (err, user) => {
135
- if (err || !user) {
136
- return res.status(401).json({ success: false, message: 'Identity node rejected credentials.' });
137
- }
138
-
139
  const match = await bcrypt.compare(password, user.password_hash);
140
  if (match) {
141
- activeSession = {
142
- id: `USR-${user.id}`,
143
- dbId: user.id, // Internal database ID for relations
144
- name: user.username,
145
- role: user.role,
146
- lastLogin: new Date().toISOString()
147
- };
148
  res.json({ success: true, user: activeSession });
149
  } else {
150
- res.status(401).json({ success: false, message: 'Identity node rejected credentials.' });
151
  }
152
  });
153
  });
 
154
 
155
- app.post('/api/auth/logout', (req, res) => {
156
- activeSession = null;
157
- res.json({ success: true });
158
- });
159
-
160
- // --- Chat History Endpoints ---
161
-
162
- app.get('/api/chat/history', (req, res) => {
163
- if (!activeSession) return res.status(401).json({ error: 'Session parity lost.' });
164
-
165
- db.all(
166
- 'SELECT * FROM messages WHERE user_id = ? ORDER BY timestamp ASC',
167
- [activeSession.dbId],
168
- (err, rows) => {
169
- if (err) return res.status(500).json({ error: 'Neural memory retrieval failure.' });
170
- res.json(rows);
171
- }
172
- );
173
- });
174
-
175
- // --- Gemini Proxy ---
176
  app.post('/api/gemini/generate', async (req, res) => {
177
  try {
178
- const apiKey = process.env.GEMINI_API_KEY;
179
- if (!apiKey) return res.status(500).json({ error: 'API Key missing' });
180
 
181
- const { model, contents, config, saveToMemory } = req.body;
182
- const ai = new GoogleGenAI({ apiKey });
183
- const response = await ai.models.generateContent({
184
- model: model || 'gemini-3-flash-preview',
185
- contents,
186
- config: config || {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
187
  });
188
 
189
- const aiText = response.text;
190
-
191
- // Persist to memory if requested and authenticated
192
- if (activeSession && saveToMemory && contents[0]?.parts[0]?.text) {
193
- const userPrompt = contents[0].parts[0].text;
194
-
195
- // Save user prompt
196
- db.run('INSERT INTO messages (user_id, role, content) VALUES (?, ?, ?)', [activeSession.dbId, 'user', userPrompt]);
197
- // Save AI response
198
- db.run('INSERT INTO messages (user_id, role, content) VALUES (?, ?, ?)', [activeSession.dbId, 'assistant', aiText]);
199
  }
200
 
201
- res.json({ text: aiText, candidates: response.candidates });
 
202
  } catch (error) {
203
- res.status(500).json({ error: 'AI communication failure', details: error.message });
204
  }
205
  });
206
 
207
- const CITI_BASE = '/api/accounts/account-transactions/partner/v1';
208
- app.get(`${CITI_BASE}/accounts/details`, (req, res) => res.json(CITI_ACCOUNTS));
209
- app.get(`${CITI_BASE}/accounts/:accountId/transactions`, (req, res) => {
210
- const { accountId } = req.params;
211
- res.json(CITI_TRANSACTIONS[accountId] || { checkingAccountTransactions: [] });
212
- });
213
 
214
- // Serve frontend files from the dist directory
215
- app.use(express.static(path.join(__dirname, 'dist')));
 
216
 
217
- // SPA Fallback: Catch any request that didn't match an API route or a static file.
218
- // In Express 5, using a middleware function without a path is the safest way
219
- // to implement a catch-all fallback for Single Page Applications.
220
  app.use((req, res) => {
221
- // Safeguard: Do not serve index.html for missing API routes
222
- if (req.path.startsWith('/api')) {
223
- return res.status(404).json({ error: 'API endpoint not found' });
224
- }
225
- res.sendFile(path.join(__dirname, 'dist', 'index.html'));
226
  });
227
 
228
- app.listen(port, '0.0.0.0', () => console.log(`Financial Node Proxy Operational on port ${port}`));
 
1
  import express from 'express';
2
  import cors from 'cors';
 
3
  import path from 'path';
4
  import { fileURLToPath } from 'url';
5
  import sqlite3 from 'sqlite3';
6
  import bcrypt from 'bcryptjs';
7
 
8
  const app = express();
 
9
  const port = process.env.PORT || 7860;
10
 
11
  // --- Database Initialization ---
 
15
  const db = new sqlite3.Database(dbPath);
16
 
17
  db.serialize(() => {
 
18
  db.run(`
19
  CREATE TABLE IF NOT EXISTS users (
20
  id INTEGER PRIMARY KEY AUTOINCREMENT,
 
24
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
25
  )
26
  `);
 
 
27
  db.run(`
28
  CREATE TABLE IF NOT EXISTS messages (
29
  id INTEGER PRIMARY KEY AUTOINCREMENT,
 
36
  `);
37
  });
38
 
 
39
  let activeSession = null;
40
 
41
+ // Mock Citi Data
42
  const CITI_ACCOUNTS = {
43
+ accountGroupDetails: [{
44
+ accountGroup: "CHECKING",
45
+ checkingAccountsDetails: [{
46
+ productName: "Corporate Mastery Checking",
47
+ accountNickname: "Main Ops Node",
48
+ accountDescription: "Corporate Mastery Checking - 9594",
49
+ balanceType: "ASSET",
50
+ displayAccountNumber: "XXXXXX9594",
51
+ accountId: "citi_acc_99201",
52
+ currencyCode: "USD",
53
+ accountStatus: "ACTIVE",
54
+ currentBalance: 1245000.50,
55
+ availableBalance: 1240000.00
56
+ }],
57
+ totalCurrentBalance: { localCurrencyCode: "USD", localCurrencyBalanceAmount: 1245000.50 },
58
+ totalAvailableBalance: { localCurrencyCode: "USD", localCurrencyBalanceAmount: 1240000.00 }
59
+ }],
60
+ customer: { customerId: "citi_cust_884102" }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  };
62
 
63
  app.use(cors());
64
  app.use(express.json());
65
  app.use(express.urlencoded({ extended: true }));
66
 
67
+ // Auth API
68
+ app.get('/api/auth/me', (req, res) => res.json({ isAuthenticated: !!activeSession, user: activeSession }));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
  app.post('/api/auth/login', (req, res) => {
70
  const { username, password } = req.body;
 
71
  db.get('SELECT * FROM users WHERE username = ?', [username], async (err, user) => {
72
+ if (err || !user) return res.status(401).json({ success: false, message: 'Invalid node' });
 
 
 
73
  const match = await bcrypt.compare(password, user.password_hash);
74
  if (match) {
75
+ activeSession = { id: `USR-${user.id}`, dbId: user.id, name: user.username, role: user.role, lastLogin: new Date().toISOString() };
 
 
 
 
 
 
76
  res.json({ success: true, user: activeSession });
77
  } else {
78
+ res.status(401).json({ success: false });
79
  }
80
  });
81
  });
82
+ app.post('/api/auth/logout', (req, res) => { activeSession = null; res.json({ success: true }); });
83
 
84
+ // Gemini REST Proxy (Using corsproxy.io and gemini-2.5-flash as requested)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  app.post('/api/gemini/generate', async (req, res) => {
86
  try {
87
+ const apiKey = process.env.GEMINI_API_KEY || process.env.API_KEY;
 
88
 
89
+ if (!apiKey) {
90
+ console.error("GEMINI_API_KEY is missing");
91
+ return res.status(500).json({ error: 'GEMINI_API_KEY missing' });
92
+ }
93
+
94
+ const { model, contents, config } = req.body;
95
+ const modelId = model || 'gemini-2.5-flash';
96
+
97
+ const targetUrl = `https://generativelanguage.googleapis.com/v1beta/models/${modelId}:generateContent`;
98
+ const proxyUrl = `https://corsproxy.io/?url=${encodeURIComponent(targetUrl)}`;
99
+
100
+ const response = await fetch(proxyUrl, {
101
+ method: 'POST',
102
+ headers: {
103
+ 'Content-Type': 'application/json',
104
+ 'x-goog-api-key': apiKey
105
+ },
106
+ body: JSON.stringify({
107
+ contents: contents,
108
+ generationConfig: config || {}
109
+ })
110
  });
111
 
112
+ const data = await response.json();
113
+
114
+ if (data.error) {
115
+ return res.status(response.status || 500).json({ error: data.error.message || 'Upstream Error' });
 
 
 
 
 
 
116
  }
117
 
118
+ const text = data.candidates?.[0]?.content?.parts?.[0]?.text || '';
119
+ res.json({ text, candidates: data.candidates });
120
  } catch (error) {
121
+ res.status(500).json({ error: error.message });
122
  }
123
  });
124
 
125
+ // Citi Proxy
126
+ app.get('/api/accounts/account-transactions/partner/v1/accounts/details', (req, res) => res.json(CITI_ACCOUNTS));
 
 
 
 
127
 
128
+ // Serve Frontend
129
+ const __dist = path.join(__dirname, 'dist');
130
+ app.use(express.static(__dist));
131
 
132
+ // SPA Fallback
 
 
133
  app.use((req, res) => {
134
+ if (req.path.startsWith('/api')) return res.status(404).json({ error: 'Not found' });
135
+ res.sendFile(path.join(__dist, 'index.html'));
 
 
 
136
  });
137
 
138
+ app.listen(port, '0.0.0.0', () => console.log(`Operational on ${port}`));