neoagent 2.1.18-beta.6 → 2.1.18-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +2 -1
- package/docs/configuration.md +2 -0
- package/package.json +1 -1
- package/server/db/database.js +46 -0
- package/server/public/flutter_bootstrap.js +1 -1
- package/server/public/main.dart.js +46015 -45933
- package/server/routes/integrations.js +35 -5
- package/server/services/ai/capabilityHealth.js +2 -2
- package/server/services/ai/engine.js +4 -2
- package/server/services/ai/tools.js +8 -0
- package/server/services/integrations/env.js +4 -1
- package/server/services/integrations/google/calendar.js +10 -2
- package/server/services/integrations/google/docs.js +45 -21
- package/server/services/integrations/google/drive.js +62 -14
- package/server/services/integrations/google/gmail.js +17 -5
- package/server/services/integrations/google/provider.js +10 -3
- package/server/services/integrations/google/sheets.js +71 -63
- package/server/services/integrations/manager.js +30 -11
- package/server/services/integrations/secrets.js +57 -0
- package/server/services/manager.js +1 -0
package/.env.example
CHANGED
|
@@ -69,7 +69,8 @@ MINIMAX_API_KEY=your-minimax-api-key-here
|
|
|
69
69
|
########################################
|
|
70
70
|
|
|
71
71
|
# Google Workspace official integration OAuth client.
|
|
72
|
-
# Redirect URI should match
|
|
72
|
+
# Redirect URI should match <PUBLIC_URL>/api/integrations/oauth/callback.
|
|
73
|
+
# Set PUBLIC_URL to your app's public base URL. Local default is http://localhost:3333.
|
|
73
74
|
GOOGLE_OAUTH_CLIENT_ID=your-google-oauth-client-id
|
|
74
75
|
GOOGLE_OAUTH_CLIENT_SECRET=your-google-oauth-client-secret
|
|
75
76
|
GOOGLE_OAUTH_REDIRECT_URI=
|
package/docs/configuration.md
CHANGED
|
@@ -42,6 +42,8 @@ At least one hosted-provider API key is required unless you only use local Ollam
|
|
|
42
42
|
| `DEEPGRAM_LANGUAGE` | Deepgram language override (defaults to `multi`) |
|
|
43
43
|
| `OLLAMA_URL` | Local Ollama (`http://localhost:11434`) |
|
|
44
44
|
|
|
45
|
+
`GOOGLE_OAUTH_CLIENT_SECRET` is sensitive, just like `SESSION_SECRET`. Do not commit it to version control, print it to logs, or expose it in client-side code. Store it in server-side environment variables or a secrets manager, restrict access to operators who need it, and rotate it immediately if you suspect it was exposed.
|
|
46
|
+
|
|
45
47
|
### Messaging
|
|
46
48
|
|
|
47
49
|
| Variable | Description |
|
package/package.json
CHANGED
package/server/db/database.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
const Database = require('better-sqlite3');
|
|
2
2
|
const path = require('path');
|
|
3
3
|
const { DATA_DIR, ensureRuntimeDirs } = require('../../runtime/paths');
|
|
4
|
+
const {
|
|
5
|
+
encryptValue,
|
|
6
|
+
isEncryptedValue,
|
|
7
|
+
} = require('../services/integrations/secrets');
|
|
4
8
|
ensureRuntimeDirs();
|
|
5
9
|
|
|
6
10
|
const DB_PATH = path.join(DATA_DIR, 'neoagent.db');
|
|
@@ -204,6 +208,7 @@ db.exec(`
|
|
|
204
208
|
CREATE INDEX IF NOT EXISTS idx_agent_steps_run ON agent_steps(run_id, step_index);
|
|
205
209
|
CREATE INDEX IF NOT EXISTS idx_integration_connections_user ON integration_connections(user_id, provider_key, app_key);
|
|
206
210
|
CREATE INDEX IF NOT EXISTS idx_integration_oauth_states_state ON integration_oauth_states(state);
|
|
211
|
+
CREATE INDEX IF NOT EXISTS idx_integration_oauth_states_expires ON integration_oauth_states(expires_at);
|
|
207
212
|
CREATE INDEX IF NOT EXISTS idx_messages_user ON messages(user_id, created_at DESC);
|
|
208
213
|
CREATE INDEX IF NOT EXISTS idx_messages_platform ON messages(platform, platform_chat_id);
|
|
209
214
|
CREATE INDEX IF NOT EXISTS idx_conv_messages ON conversation_messages(conversation_id, created_at);
|
|
@@ -379,6 +384,12 @@ db.exec(`
|
|
|
379
384
|
CREATE INDEX IF NOT EXISTS idx_recording_sources_session ON recording_sources(session_id, source_key);
|
|
380
385
|
CREATE INDEX IF NOT EXISTS idx_recording_chunks_source ON recording_chunks(source_id, sequence_index);
|
|
381
386
|
CREATE INDEX IF NOT EXISTS idx_recording_segments_session ON recording_transcript_segments(session_id, start_ms, created_at);
|
|
387
|
+
|
|
388
|
+
CREATE TRIGGER IF NOT EXISTS cleanup_expired_oauth_states
|
|
389
|
+
AFTER INSERT ON integration_oauth_states BEGIN
|
|
390
|
+
DELETE FROM integration_oauth_states
|
|
391
|
+
WHERE datetime(expires_at) <= datetime('now');
|
|
392
|
+
END;
|
|
382
393
|
`);
|
|
383
394
|
|
|
384
395
|
try {
|
|
@@ -581,8 +592,43 @@ function migrateIntegrationOauthStatesTable() {
|
|
|
581
592
|
`);
|
|
582
593
|
}
|
|
583
594
|
|
|
595
|
+
function migrateIntegrationSecretStorage() {
|
|
596
|
+
try {
|
|
597
|
+
const connectionRows = db
|
|
598
|
+
.prepare('SELECT id, credentials_json FROM integration_connections')
|
|
599
|
+
.all();
|
|
600
|
+
const updateConnection = db.prepare(
|
|
601
|
+
'UPDATE integration_connections SET credentials_json = ? WHERE id = ?',
|
|
602
|
+
);
|
|
603
|
+
for (const row of connectionRows) {
|
|
604
|
+
const current = String(row.credentials_json || '');
|
|
605
|
+
if (!current || isEncryptedValue(current)) continue;
|
|
606
|
+
updateConnection.run(encryptValue(current), row.id);
|
|
607
|
+
}
|
|
608
|
+
} catch {
|
|
609
|
+
// Preserve startup even if a row cannot be re-encrypted.
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
try {
|
|
613
|
+
const stateRows = db
|
|
614
|
+
.prepare('SELECT id, code_verifier FROM integration_oauth_states')
|
|
615
|
+
.all();
|
|
616
|
+
const updateState = db.prepare(
|
|
617
|
+
'UPDATE integration_oauth_states SET code_verifier = ? WHERE id = ?',
|
|
618
|
+
);
|
|
619
|
+
for (const row of stateRows) {
|
|
620
|
+
const current = String(row.code_verifier || '');
|
|
621
|
+
if (!current || isEncryptedValue(current)) continue;
|
|
622
|
+
updateState.run(encryptValue(current), row.id);
|
|
623
|
+
}
|
|
624
|
+
} catch {
|
|
625
|
+
// Preserve startup even if a row cannot be re-encrypted.
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
584
629
|
migrateIntegrationConnectionsTable();
|
|
585
630
|
migrateIntegrationOauthStatesTable();
|
|
631
|
+
migrateIntegrationSecretStorage();
|
|
586
632
|
|
|
587
633
|
try {
|
|
588
634
|
db.exec(`
|
|
@@ -37,6 +37,6 @@ _flutter.buildConfig = {"engineRevision":"425cfb54d01a9472b3e81d9e76fd63a4a44cfb
|
|
|
37
37
|
|
|
38
38
|
_flutter.loader.load({
|
|
39
39
|
serviceWorkerSettings: {
|
|
40
|
-
serviceWorkerVersion: "
|
|
40
|
+
serviceWorkerVersion: "1552279196" /* Flutter's service worker is deprecated and will be removed in a future Flutter release. */
|
|
41
41
|
}
|
|
42
42
|
});
|