nothumanallowed 16.0.8 → 16.0.9
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nothumanallowed",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.9",
|
|
4
4
|
"description": "NotHumanAllowed — 38 AI agents, 80 tools, Studio (visual agentic workflows). Email, calendar, browser automation, screen capture, canvas, cron/heartbeat, Alexandria E2E messaging, GitHub, Notion, Slack, voice chat, free AI (Liara), 28 languages. Zero-dependency CLI.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/constants.mjs
CHANGED
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'url';
|
|
|
5
5
|
const __filename = fileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = path.dirname(__filename);
|
|
7
7
|
|
|
8
|
-
export const VERSION = '16.0.
|
|
8
|
+
export const VERSION = '16.0.9';
|
|
9
9
|
export const BASE_URL = 'https://nothumanallowed.com/cli';
|
|
10
10
|
export const API_BASE = 'https://nothumanallowed.com/api/v1';
|
|
11
11
|
|
|
@@ -11,6 +11,14 @@ export function register(router) {
|
|
|
11
11
|
router.post('/api/google/auth', async (req, res) => {
|
|
12
12
|
try {
|
|
13
13
|
const { buildAuthUrl } = await import('../../services/google-oauth.mjs');
|
|
14
|
+
// Wipe out any cached refresh_token BEFORE starting a new flow.
|
|
15
|
+
// Otherwise Google can return a fresh access_token with the OLD scopes
|
|
16
|
+
// (using the still-valid refresh_token) and the user never gets the
|
|
17
|
+
// new permissions even after re-authorizing.
|
|
18
|
+
try {
|
|
19
|
+
const { deleteTokens } = await import('../../services/token-store.mjs');
|
|
20
|
+
deleteTokens('google');
|
|
21
|
+
} catch {}
|
|
14
22
|
const config = loadConfig();
|
|
15
23
|
const host = req.headers['host'] || 'localhost:3847';
|
|
16
24
|
const redirectUri = `http://${host}/api/google/callback`;
|
|
@@ -20,6 +28,37 @@ export function register(router) {
|
|
|
20
28
|
} catch (e) { sendError(res, 500, e.message); }
|
|
21
29
|
});
|
|
22
30
|
|
|
31
|
+
// GET /api/google/status — diagnostic: what scopes does the current token
|
|
32
|
+
// actually have? Used by the Settings UI to highlight missing scopes.
|
|
33
|
+
router.get('/api/google/status', async (_req, res) => {
|
|
34
|
+
try {
|
|
35
|
+
const { loadTokens } = await import('../../services/token-store.mjs');
|
|
36
|
+
const tokens = loadTokens('google');
|
|
37
|
+
if (!tokens) return sendJSON(res, 200, { authenticated: false });
|
|
38
|
+
const scopeStr = tokens.scope || '';
|
|
39
|
+
const scopes = scopeStr.split(/\s+/).filter(Boolean);
|
|
40
|
+
const required = {
|
|
41
|
+
'gmail.modify': scopes.includes('https://www.googleapis.com/auth/gmail.modify'),
|
|
42
|
+
'gmail.send': scopes.includes('https://www.googleapis.com/auth/gmail.send'),
|
|
43
|
+
'calendar.events': scopes.includes('https://www.googleapis.com/auth/calendar.events'),
|
|
44
|
+
'drive.readonly': scopes.includes('https://www.googleapis.com/auth/drive.readonly'),
|
|
45
|
+
'drive.file': scopes.includes('https://www.googleapis.com/auth/drive.file'),
|
|
46
|
+
'contacts': scopes.includes('https://www.googleapis.com/auth/contacts'),
|
|
47
|
+
'tasks': scopes.includes('https://www.googleapis.com/auth/tasks'),
|
|
48
|
+
};
|
|
49
|
+
const missing = Object.entries(required).filter(([, v]) => !v).map(([k]) => k);
|
|
50
|
+
sendJSON(res, 200, {
|
|
51
|
+
authenticated: true,
|
|
52
|
+
email: tokens.email,
|
|
53
|
+
scopes,
|
|
54
|
+
scopeCheck: required,
|
|
55
|
+
missing,
|
|
56
|
+
canWriteDrive: required['drive.file'],
|
|
57
|
+
expiresAt: tokens.expires_at,
|
|
58
|
+
});
|
|
59
|
+
} catch (e) { sendError(res, 500, e.message); }
|
|
60
|
+
});
|
|
61
|
+
|
|
23
62
|
router.get('/api/google/callback', async (req, res) => {
|
|
24
63
|
const url = new URL(req.url, 'http://localhost');
|
|
25
64
|
const code = url.searchParams.get('code');
|