crewly 1.5.22 → 1.6.1
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/config/roles/orchestrator/fragments/role-boundary.md +4 -1
- package/config/roles/orchestrator/prompt.md +219 -25
- package/config/roles/orchestrator/soul.md +47 -10
- package/config/skills/_common/lib.sh +28 -0
- package/config/skills/agent/core/cancel-followup/SKILL.md +38 -0
- package/config/skills/agent/core/cancel-followup/execute.sh +92 -0
- package/config/skills/agent/core/cancel-followup/execute.test.sh +42 -0
- package/config/skills/agent/core/list-my-followups/SKILL.md +36 -0
- package/config/skills/agent/core/list-my-followups/execute.sh +74 -0
- package/config/skills/agent/core/list-my-followups/execute.test.sh +41 -0
- package/config/skills/agent/core/schedule-followup/SKILL.md +53 -0
- package/config/skills/agent/core/schedule-followup/execute.sh +176 -0
- package/config/skills/agent/core/schedule-followup/execute.test.sh +48 -0
- package/config/skills/agent/core/watch-for-event/SKILL.md +60 -0
- package/config/skills/agent/core/watch-for-event/execute.sh +158 -0
- package/config/skills/agent/core/watch-for-event/execute.test.sh +43 -0
- package/config/skills/orchestrator/credential-manager/SKILL.md +218 -0
- package/config/skills/orchestrator/credential-manager/execute.sh +166 -0
- package/config/skills/orchestrator/credential-manager/execute.test.sh +88 -0
- package/dist/backend/backend/src/config/oauth.config.d.ts +33 -0
- package/dist/backend/backend/src/config/oauth.config.d.ts.map +1 -0
- package/dist/backend/backend/src/config/oauth.config.js +45 -0
- package/dist/backend/backend/src/config/oauth.config.js.map +1 -0
- package/dist/backend/backend/src/controllers/credentials/credentials.controller.d.ts +54 -0
- package/dist/backend/backend/src/controllers/credentials/credentials.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/credentials/credentials.controller.js +228 -0
- package/dist/backend/backend/src/controllers/credentials/credentials.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/credentials/credentials.routes.d.ts +26 -0
- package/dist/backend/backend/src/controllers/credentials/credentials.routes.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/credentials/credentials.routes.js +41 -0
- package/dist/backend/backend/src/controllers/credentials/credentials.routes.js.map +1 -0
- package/dist/backend/backend/src/controllers/credentials/google-oauth.controller.d.ts +40 -0
- package/dist/backend/backend/src/controllers/credentials/google-oauth.controller.d.ts.map +1 -0
- package/dist/backend/backend/src/controllers/credentials/google-oauth.controller.js +162 -0
- package/dist/backend/backend/src/controllers/credentials/google-oauth.controller.js.map +1 -0
- package/dist/backend/backend/src/controllers/skill/skill.controller.d.ts.map +1 -1
- package/dist/backend/backend/src/controllers/skill/skill.controller.js +1 -0
- package/dist/backend/backend/src/controllers/skill/skill.controller.js.map +1 -1
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js +23 -14
- package/dist/backend/backend/src/controllers/task-pool/task-pool.controller.js.map +1 -1
- package/dist/backend/backend/src/index.d.ts.map +1 -1
- package/dist/backend/backend/src/index.js +23 -4
- package/dist/backend/backend/src/index.js.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.d.ts.map +1 -1
- package/dist/backend/backend/src/routes/api.routes.js +3 -0
- package/dist/backend/backend/src/routes/api.routes.js.map +1 -1
- package/dist/backend/backend/src/scripts/backfill-mission-priority.d.ts +3 -1
- package/dist/backend/backend/src/scripts/backfill-mission-priority.d.ts.map +1 -1
- package/dist/backend/backend/src/scripts/backfill-mission-priority.js +16 -4
- package/dist/backend/backend/src/scripts/backfill-mission-priority.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js +4 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/role-boundary.module.js.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.d.ts.map +1 -1
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js +17 -0
- package/dist/backend/backend/src/services/ai/prompt-modules/skills-reference.module.js.map +1 -1
- package/dist/backend/backend/src/services/browser/browser-proxy.service.js +1 -1
- package/dist/backend/backend/src/services/browser/browser-proxy.service.js.map +1 -1
- package/dist/backend/backend/src/services/credential/credential-store.service.d.ts +161 -0
- package/dist/backend/backend/src/services/credential/credential-store.service.d.ts.map +1 -0
- package/dist/backend/backend/src/services/credential/credential-store.service.js +298 -0
- package/dist/backend/backend/src/services/credential/credential-store.service.js.map +1 -0
- package/dist/backend/backend/src/services/credential/helpers/gemini-cli-workspace.helper.d.ts +105 -0
- package/dist/backend/backend/src/services/credential/helpers/gemini-cli-workspace.helper.d.ts.map +1 -0
- package/dist/backend/backend/src/services/credential/helpers/gemini-cli-workspace.helper.js +272 -0
- package/dist/backend/backend/src/services/credential/helpers/gemini-cli-workspace.helper.js.map +1 -0
- package/dist/backend/backend/src/services/mcp-server.d.ts +46 -2
- package/dist/backend/backend/src/services/mcp-server.d.ts.map +1 -1
- package/dist/backend/backend/src/services/mcp-server.js +216 -211
- package/dist/backend/backend/src/services/mcp-server.js.map +1 -1
- package/dist/backend/backend/src/services/mcp-tool-definitions.d.ts +254 -0
- package/dist/backend/backend/src/services/mcp-tool-definitions.d.ts.map +1 -0
- package/dist/backend/backend/src/services/mcp-tool-definitions.js +285 -0
- package/dist/backend/backend/src/services/mcp-tool-definitions.js.map +1 -0
- package/dist/backend/backend/src/services/project/task.service.d.ts +18 -2
- package/dist/backend/backend/src/services/project/task.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/project/task.service.js +74 -53
- package/dist/backend/backend/src/services/project/task.service.js.map +1 -1
- package/dist/backend/backend/src/services/skill/skill-executor.service.d.ts +41 -0
- package/dist/backend/backend/src/services/skill/skill-executor.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/skill/skill-executor.service.js +136 -7
- package/dist/backend/backend/src/services/skill/skill-executor.service.js.map +1 -1
- package/dist/backend/backend/src/services/skill/skill.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/skill/skill.service.js +1 -0
- package/dist/backend/backend/src/services/skill/skill.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/contract-matcher.d.ts +20 -0
- package/dist/backend/backend/src/services/v3/contract-matcher.d.ts.map +1 -0
- package/dist/backend/backend/src/services/v3/contract-matcher.js +33 -0
- package/dist/backend/backend/src/services/v3/contract-matcher.js.map +1 -0
- package/dist/backend/backend/src/services/v3/escalation.service.d.ts +20 -1
- package/dist/backend/backend/src/services/v3/escalation.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/escalation.service.js +97 -28
- package/dist/backend/backend/src/services/v3/escalation.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/service-contract-gate.service.d.ts +6 -4
- package/dist/backend/backend/src/services/v3/service-contract-gate.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/service-contract-gate.service.js +18 -28
- package/dist/backend/backend/src/services/v3/service-contract-gate.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/team-trigger-reconciler.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/team-trigger-reconciler.service.js +14 -9
- package/dist/backend/backend/src/services/v3/team-trigger-reconciler.service.js.map +1 -1
- package/dist/backend/backend/src/services/v3/trigger-engine.service.d.ts +34 -1
- package/dist/backend/backend/src/services/v3/trigger-engine.service.d.ts.map +1 -1
- package/dist/backend/backend/src/services/v3/trigger-engine.service.js +115 -5
- package/dist/backend/backend/src/services/v3/trigger-engine.service.js.map +1 -1
- package/dist/backend/backend/src/types/credential.types.d.ts +185 -0
- package/dist/backend/backend/src/types/credential.types.d.ts.map +1 -0
- package/dist/backend/backend/src/types/credential.types.js +76 -0
- package/dist/backend/backend/src/types/credential.types.js.map +1 -0
- package/dist/backend/backend/src/types/skill.types.d.ts +9 -0
- package/dist/backend/backend/src/types/skill.types.d.ts.map +1 -1
- package/dist/backend/backend/src/types/skill.types.js.map +1 -1
- package/dist/backend/backend/src/utils/encryption.utils.d.ts +57 -0
- package/dist/backend/backend/src/utils/encryption.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/utils/encryption.utils.js +162 -0
- package/dist/backend/backend/src/utils/encryption.utils.js.map +1 -0
- package/dist/backend/backend/src/utils/google-userinfo.utils.d.ts +41 -0
- package/dist/backend/backend/src/utils/google-userinfo.utils.d.ts.map +1 -0
- package/dist/backend/backend/src/utils/google-userinfo.utils.js +44 -0
- package/dist/backend/backend/src/utils/google-userinfo.utils.js.map +1 -0
- package/dist/cli/backend/src/config/oauth.config.d.ts +33 -0
- package/dist/cli/backend/src/config/oauth.config.d.ts.map +1 -0
- package/dist/cli/backend/src/config/oauth.config.js +45 -0
- package/dist/cli/backend/src/config/oauth.config.js.map +1 -0
- package/dist/cli/backend/src/services/credential/credential-store.service.d.ts +161 -0
- package/dist/cli/backend/src/services/credential/credential-store.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/credential/credential-store.service.js +298 -0
- package/dist/cli/backend/src/services/credential/credential-store.service.js.map +1 -0
- package/dist/cli/backend/src/services/credential/helpers/gemini-cli-workspace.helper.d.ts +105 -0
- package/dist/cli/backend/src/services/credential/helpers/gemini-cli-workspace.helper.d.ts.map +1 -0
- package/dist/cli/backend/src/services/credential/helpers/gemini-cli-workspace.helper.js +272 -0
- package/dist/cli/backend/src/services/credential/helpers/gemini-cli-workspace.helper.js.map +1 -0
- package/dist/cli/backend/src/services/mcp-server.d.ts +46 -2
- package/dist/cli/backend/src/services/mcp-server.d.ts.map +1 -1
- package/dist/cli/backend/src/services/mcp-server.js +216 -211
- package/dist/cli/backend/src/services/mcp-server.js.map +1 -1
- package/dist/cli/backend/src/services/mcp-tool-definitions.d.ts +254 -0
- package/dist/cli/backend/src/services/mcp-tool-definitions.d.ts.map +1 -0
- package/dist/cli/backend/src/services/mcp-tool-definitions.js +285 -0
- package/dist/cli/backend/src/services/mcp-tool-definitions.js.map +1 -0
- package/dist/cli/backend/src/services/settings/settings.service.d.ts +168 -0
- package/dist/cli/backend/src/services/settings/settings.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/settings/settings.service.js +312 -0
- package/dist/cli/backend/src/services/settings/settings.service.js.map +1 -0
- package/dist/cli/backend/src/services/skill/skill-executor.service.d.ts +177 -0
- package/dist/cli/backend/src/services/skill/skill-executor.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/skill/skill-executor.service.js +624 -0
- package/dist/cli/backend/src/services/skill/skill-executor.service.js.map +1 -0
- package/dist/cli/backend/src/services/skill/skill.service.d.ts +273 -0
- package/dist/cli/backend/src/services/skill/skill.service.d.ts.map +1 -0
- package/dist/cli/backend/src/services/skill/skill.service.js +655 -0
- package/dist/cli/backend/src/services/skill/skill.service.js.map +1 -0
- package/dist/cli/backend/src/types/credential.types.d.ts +185 -0
- package/dist/cli/backend/src/types/credential.types.d.ts.map +1 -0
- package/dist/cli/backend/src/types/credential.types.js +76 -0
- package/dist/cli/backend/src/types/credential.types.js.map +1 -0
- package/dist/cli/backend/src/types/skill.types.d.ts +9 -0
- package/dist/cli/backend/src/types/skill.types.d.ts.map +1 -1
- package/dist/cli/backend/src/types/skill.types.js.map +1 -1
- package/dist/cli/backend/src/utils/encryption.utils.d.ts +57 -0
- package/dist/cli/backend/src/utils/encryption.utils.d.ts.map +1 -0
- package/dist/cli/backend/src/utils/encryption.utils.js +162 -0
- package/dist/cli/backend/src/utils/encryption.utils.js.map +1 -0
- package/dist/cli/backend/src/utils/google-userinfo.utils.d.ts +41 -0
- package/dist/cli/backend/src/utils/google-userinfo.utils.d.ts.map +1 -0
- package/dist/cli/backend/src/utils/google-userinfo.utils.js +44 -0
- package/dist/cli/backend/src/utils/google-userinfo.utils.js.map +1 -0
- package/dist/cli/backend/src/utils/skill-md-parser.d.ts +38 -0
- package/dist/cli/backend/src/utils/skill-md-parser.d.ts.map +1 -0
- package/dist/cli/backend/src/utils/skill-md-parser.js +47 -0
- package/dist/cli/backend/src/utils/skill-md-parser.js.map +1 -0
- package/frontend/dist/assets/{index-dc92ab64.css → index-6aaa0630.css} +1 -1
- package/frontend/dist/assets/{index-76d76633.js → index-70356616.js} +334 -328
- package/frontend/dist/index.html +2 -2
- package/package.json +1 -1
- package/config/experts/empathetic-resolver/expert.json +0 -11
- package/config/experts/empathetic-resolver.md +0 -32
- package/config/experts/pragmatic-architect/expert.json +0 -11
- package/config/experts/pragmatic-architect.md +0 -32
- package/config/experts/viral-alchemist/expert.json +0 -11
- package/config/experts/viral-alchemist.md +0 -32
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Credential Manager
|
|
3
|
+
description: "Manage workspace credentials (Google OAuth accounts, service API keys) that skills use to call third-party services on the user's behalf. Primary flow for remote users over Slack: start-google-oauth returns a link the user clicks on their device; they sign in and paste the resulting JSON back, then complete-google-oauth saves the credential. Supports multi-account."
|
|
4
|
+
version: 1.1.0
|
|
5
|
+
category: management
|
|
6
|
+
skillType: claude-skill
|
|
7
|
+
assignableRoles:
|
|
8
|
+
- orchestrator
|
|
9
|
+
triggers:
|
|
10
|
+
- add gmail account
|
|
11
|
+
- add google account
|
|
12
|
+
- add api key
|
|
13
|
+
- list credentials
|
|
14
|
+
- show credentials
|
|
15
|
+
- what credentials
|
|
16
|
+
- delete credential
|
|
17
|
+
- revoke credential
|
|
18
|
+
- connect google
|
|
19
|
+
- connect gmail
|
|
20
|
+
- read gmail
|
|
21
|
+
- check unread emails
|
|
22
|
+
- unread messages
|
|
23
|
+
- my inbox
|
|
24
|
+
tags:
|
|
25
|
+
- credentials
|
|
26
|
+
- oauth
|
|
27
|
+
- gmail
|
|
28
|
+
- google
|
|
29
|
+
- api-key
|
|
30
|
+
execution:
|
|
31
|
+
type: script
|
|
32
|
+
script:
|
|
33
|
+
file: execute.sh
|
|
34
|
+
interpreter: bash
|
|
35
|
+
timeoutMs: 30000
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
# Credential Manager
|
|
39
|
+
|
|
40
|
+
Manages the workspace's credential store used by skills. Supports Google OAuth
|
|
41
|
+
(multi-account) and API keys.
|
|
42
|
+
|
|
43
|
+
**Credential values are never returned** — only metadata (id, name, email,
|
|
44
|
+
scopes). The actual tokens stay encrypted on disk and are only exposed to
|
|
45
|
+
skills at execution time via per-slot env vars.
|
|
46
|
+
|
|
47
|
+
## Primary flow: Remote user via Slack
|
|
48
|
+
|
|
49
|
+
The user is on Slack and cannot run terminal commands. Use this flow:
|
|
50
|
+
|
|
51
|
+
### 1. Start — return a sign-in link
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
bash execute.sh '{"action":"start-google-oauth"}'
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Returns:
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"success": true,
|
|
61
|
+
"authUrl": "https://accounts.google.com/o/oauth2/v2/auth?client_id=...&scope=...",
|
|
62
|
+
"instructions": "Send authUrl to the user. They click it..."
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Send the `authUrl` to the user**. Tell them:
|
|
67
|
+
> Please click this link, sign in with the Google account you want to add,
|
|
68
|
+
> then copy the entire JSON block shown on the success page and paste it back here.
|
|
69
|
+
|
|
70
|
+
The URL opens on their device (phone, laptop, whatever). Google shows the
|
|
71
|
+
consent screen ("Google Workspace Extension for Gemini CLI wants to access...").
|
|
72
|
+
After they approve, they land on a page titled **"Success! Credentials Ready"**
|
|
73
|
+
with a JSON block like:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"refresh_token": "1//...",
|
|
78
|
+
"scope": "...",
|
|
79
|
+
"token_type": "Bearer",
|
|
80
|
+
"access_token": "ya29...",
|
|
81
|
+
"expiry_date": 1234567890123
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. Complete — save the credential
|
|
86
|
+
|
|
87
|
+
After the user pastes the JSON back, call:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
bash execute.sh '{
|
|
91
|
+
"action":"complete-google-oauth",
|
|
92
|
+
"name":"info-steam-fun",
|
|
93
|
+
"credentialsJson": {"refresh_token":"...","access_token":"...","scope":"...","token_type":"Bearer","expiry_date":...}
|
|
94
|
+
}'
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"success": true,
|
|
101
|
+
"credential": {
|
|
102
|
+
"id": "cred-abc123...",
|
|
103
|
+
"name": "info-steam-fun",
|
|
104
|
+
"type": "google-oauth",
|
|
105
|
+
"provider": "google",
|
|
106
|
+
"helper": "gemini-cli-workspace",
|
|
107
|
+
"accountEmail": "info@steam-fun.com",
|
|
108
|
+
"scopes": [...]
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### 3. Repeat for more accounts
|
|
114
|
+
|
|
115
|
+
Just call `start-google-oauth` → send new URL → `complete-google-oauth` again
|
|
116
|
+
with a different name. No extension state to clear (headless mode never
|
|
117
|
+
touches it).
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Developer flow (on-box only)
|
|
122
|
+
|
|
123
|
+
If you're running on the same machine as Crewly AND have the Gemini CLI
|
|
124
|
+
Workspace extension set up for interactive login, these still work:
|
|
125
|
+
|
|
126
|
+
### `import-google`
|
|
127
|
+
|
|
128
|
+
Import the extension's currently-active login:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
bash execute.sh '{"action":"import-google","name":"info-steam-fun"}'
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Precondition: user has run `GEMINI_CLI_WORKSPACE_FORCE_FILE_STORAGE=true gemini`
|
|
135
|
+
and completed sign-in, leaving tokens in the extension's file cache.
|
|
136
|
+
|
|
137
|
+
### `clear-gemini-cli`
|
|
138
|
+
|
|
139
|
+
Delete the extension's cached token file so the next local login captures
|
|
140
|
+
a fresh account:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
bash execute.sh '{"action":"clear-gemini-cli"}'
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Other actions
|
|
149
|
+
|
|
150
|
+
### `list`
|
|
151
|
+
|
|
152
|
+
List credentials (filter optional).
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
bash execute.sh '{"action":"list"}'
|
|
156
|
+
bash execute.sh '{"action":"list","type":"google-oauth"}'
|
|
157
|
+
bash execute.sh '{"action":"list","provider":"gemini"}'
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### `add-api-key`
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
bash execute.sh '{"action":"add-api-key","name":"gemini-main","provider":"gemini","value":"AIza..."}'
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### `delete`
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
bash execute.sh '{"action":"delete","id":"cred-abc123..."}'
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### `read-gmail`
|
|
173
|
+
|
|
174
|
+
Read unread emails from the named Google account:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
bash execute.sh '{"action":"read-gmail","name":"info-steam-fun"}'
|
|
178
|
+
bash execute.sh '{"action":"read-gmail","name":"personal-gmail","maxResults":5}'
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Multi-account example (remote Slack user)
|
|
184
|
+
|
|
185
|
+
```
|
|
186
|
+
User: "Add info@steam-fun.com to Crewly"
|
|
187
|
+
Orchestrator:
|
|
188
|
+
1. bash execute.sh '{"action":"start-google-oauth"}'
|
|
189
|
+
2. Gets authUrl back.
|
|
190
|
+
3. Replies in Slack:
|
|
191
|
+
"Click this to sign in with info@steam-fun.com: <authUrl>
|
|
192
|
+
After signing in, copy the JSON block from the 'Success!' page
|
|
193
|
+
and paste it back here."
|
|
194
|
+
|
|
195
|
+
User: (clicks on phone, signs in, pastes JSON)
|
|
196
|
+
{"refresh_token":"...","access_token":"...","scope":"...","token_type":"Bearer","expiry_date":...}
|
|
197
|
+
|
|
198
|
+
Orchestrator:
|
|
199
|
+
1. bash execute.sh '{"action":"complete-google-oauth","name":"info-steam-fun","credentialsJson":<pasted JSON>}'
|
|
200
|
+
2. Replies: "✓ Added info-steam-fun (info@steam-fun.com)."
|
|
201
|
+
|
|
202
|
+
User: "Now add my personal gmail"
|
|
203
|
+
Orchestrator:
|
|
204
|
+
repeats start → URL → user pastes → complete, with name=personal-gmail.
|
|
205
|
+
|
|
206
|
+
User: "What's unread in info's inbox?"
|
|
207
|
+
Orchestrator:
|
|
208
|
+
bash execute.sh '{"action":"read-gmail","name":"info-steam-fun"}'
|
|
209
|
+
→ returns summary of unread emails.
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Errors
|
|
213
|
+
|
|
214
|
+
- `name is required` / `credentialsJson is required` — missing fields in complete action
|
|
215
|
+
- `credentialsJson is not valid JSON` — user pasted something other than the JSON block
|
|
216
|
+
- `credentialsJson is missing access_token or refresh_token` — user pasted a partial JSON
|
|
217
|
+
- `No google-oauth credential found with name '...'` — `read-gmail` lookup failed; try `list`
|
|
218
|
+
- `Credential '...' is revoked` — the refresh token was revoked by the user or Google; re-run the OAuth flow
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Credential Manager — wraps /api/credentials REST endpoints so the
|
|
3
|
+
# orchestrator can manage Google OAuth accounts and API keys on user request.
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
|
+
source "${SCRIPT_DIR}/../_common/lib.sh"
|
|
7
|
+
|
|
8
|
+
INPUT=$(read_json_input "${1:-}")
|
|
9
|
+
if [ -z "$INPUT" ]; then
|
|
10
|
+
error_exit "Usage: execute.sh '{\"action\":\"list|import-google|clear-gemini-cli|add-api-key|delete|read-gmail\", ...}'"
|
|
11
|
+
fi
|
|
12
|
+
|
|
13
|
+
ACTION=$(printf '%s' "$INPUT" | jq -r '.action // empty')
|
|
14
|
+
require_param "action" "$ACTION"
|
|
15
|
+
|
|
16
|
+
case "$ACTION" in
|
|
17
|
+
list)
|
|
18
|
+
TYPE=$(printf '%s' "$INPUT" | jq -r '.type // empty')
|
|
19
|
+
PROVIDER=$(printf '%s' "$INPUT" | jq -r '.provider // empty')
|
|
20
|
+
RESP=$(api_call GET "/credentials")
|
|
21
|
+
# Filter client-side
|
|
22
|
+
printf '%s' "$RESP" | jq --arg type "$TYPE" --arg provider "$PROVIDER" '
|
|
23
|
+
.data
|
|
24
|
+
| map(select($type == "" or .type == $type))
|
|
25
|
+
| map(select($provider == "" or .provider == $provider))
|
|
26
|
+
| map({id, name, type, provider, helper, accountEmail, scopes, status, createdAt, lastUsedAt})
|
|
27
|
+
'
|
|
28
|
+
;;
|
|
29
|
+
|
|
30
|
+
import-google)
|
|
31
|
+
# Import from gemini-cli extension's LOCAL file (developer / on-box user).
|
|
32
|
+
# For remote users over Slack, use start-google-oauth + complete-google-oauth instead.
|
|
33
|
+
NAME=$(printf '%s' "$INPUT" | jq -r '.name // empty')
|
|
34
|
+
require_param "name" "$NAME"
|
|
35
|
+
BODY=$(jq -nc --arg name "$NAME" '{name: $name}')
|
|
36
|
+
RESP=$(api_call POST "/credentials/oauth/import-gemini-cli" "$BODY")
|
|
37
|
+
printf '%s' "$RESP" | jq '
|
|
38
|
+
if .success == true then
|
|
39
|
+
{success: true, credential: .data | {id, name, type, provider, helper, accountEmail, scopes}}
|
|
40
|
+
else
|
|
41
|
+
{success: false, error: .error}
|
|
42
|
+
end
|
|
43
|
+
'
|
|
44
|
+
;;
|
|
45
|
+
|
|
46
|
+
start-google-oauth)
|
|
47
|
+
# Headless flow — returns a URL for a remote user to click.
|
|
48
|
+
# Optionally takes scopes override; defaults to broad Workspace set.
|
|
49
|
+
SCOPES_ARG=$(printf '%s' "$INPUT" | jq -c '.scopes // empty')
|
|
50
|
+
if [ -n "$SCOPES_ARG" ]; then
|
|
51
|
+
BODY=$(printf '%s' "$SCOPES_ARG" | jq -c '{scopes: .}')
|
|
52
|
+
else
|
|
53
|
+
BODY='{}'
|
|
54
|
+
fi
|
|
55
|
+
RESP=$(api_call POST "/credentials/oauth/google/start" "$BODY")
|
|
56
|
+
printf '%s' "$RESP" | jq '
|
|
57
|
+
if .success == true then
|
|
58
|
+
{
|
|
59
|
+
success: true,
|
|
60
|
+
authUrl: .data.authUrl,
|
|
61
|
+
instructions: "Send authUrl to the user. They click it on their device, sign in with the Google account they want to add, and copy the JSON shown on the success page. Then call action=complete-google-oauth with the pasted JSON."
|
|
62
|
+
}
|
|
63
|
+
else
|
|
64
|
+
{success: false, error: .error}
|
|
65
|
+
end
|
|
66
|
+
'
|
|
67
|
+
;;
|
|
68
|
+
|
|
69
|
+
complete-google-oauth)
|
|
70
|
+
# Accept the JSON the user pasted from the success page. Save as a new credential.
|
|
71
|
+
NAME=$(printf '%s' "$INPUT" | jq -r '.name // empty')
|
|
72
|
+
require_param "name" "$NAME"
|
|
73
|
+
# Accept either the raw JSON string or a parsed object under .credentialsJson
|
|
74
|
+
CREDS=$(printf '%s' "$INPUT" | jq -c '.credentialsJson // empty')
|
|
75
|
+
if [ -z "$CREDS" ] || [ "$CREDS" = "null" ]; then
|
|
76
|
+
error_exit "credentialsJson is required (paste the JSON block from the OAuth success page)"
|
|
77
|
+
fi
|
|
78
|
+
BODY=$(jq -nc --arg name "$NAME" --argjson creds "$CREDS" '{name: $name, credentialsJson: $creds}')
|
|
79
|
+
RESP=$(api_call POST "/credentials/oauth/google/complete" "$BODY")
|
|
80
|
+
printf '%s' "$RESP" | jq '
|
|
81
|
+
if .success == true then
|
|
82
|
+
{success: true, credential: .data | {id, name, type, provider, helper, accountEmail, scopes, status}}
|
|
83
|
+
else
|
|
84
|
+
{success: false, error: .error}
|
|
85
|
+
end
|
|
86
|
+
'
|
|
87
|
+
;;
|
|
88
|
+
|
|
89
|
+
clear-gemini-cli)
|
|
90
|
+
api_call POST "/credentials/oauth/gemini-cli/clear-extension-file" "" \
|
|
91
|
+
| jq '{cleared: (.success == true), error: .error}'
|
|
92
|
+
;;
|
|
93
|
+
|
|
94
|
+
add-api-key)
|
|
95
|
+
NAME=$(printf '%s' "$INPUT" | jq -r '.name // empty')
|
|
96
|
+
PROVIDER=$(printf '%s' "$INPUT" | jq -r '.provider // empty')
|
|
97
|
+
VALUE=$(printf '%s' "$INPUT" | jq -r '.value // empty')
|
|
98
|
+
require_param "name" "$NAME"
|
|
99
|
+
require_param "provider" "$PROVIDER"
|
|
100
|
+
require_param "value" "$VALUE"
|
|
101
|
+
BODY=$(jq -nc --arg name "$NAME" --arg provider "$PROVIDER" --arg value "$VALUE" \
|
|
102
|
+
'{name: $name, provider: $provider, value: $value}')
|
|
103
|
+
RESP=$(api_call POST "/credentials/api-key" "$BODY")
|
|
104
|
+
printf '%s' "$RESP" | jq '
|
|
105
|
+
if .success == true then
|
|
106
|
+
{success: true, credential: .data | {id, name, type, provider, createdAt}}
|
|
107
|
+
else
|
|
108
|
+
{success: false, error: .error}
|
|
109
|
+
end
|
|
110
|
+
'
|
|
111
|
+
;;
|
|
112
|
+
|
|
113
|
+
delete)
|
|
114
|
+
ID=$(printf '%s' "$INPUT" | jq -r '.id // empty')
|
|
115
|
+
require_param "id" "$ID"
|
|
116
|
+
api_call DELETE "/credentials/${ID}" | jq '{deleted: (.success == true), error: .error}'
|
|
117
|
+
;;
|
|
118
|
+
|
|
119
|
+
read-gmail)
|
|
120
|
+
NAME=$(printf '%s' "$INPUT" | jq -r '.name // empty')
|
|
121
|
+
MAX=$(printf '%s' "$INPUT" | jq -r '.maxResults // 10')
|
|
122
|
+
require_param "name" "$NAME"
|
|
123
|
+
|
|
124
|
+
# 1. Find the credential by name
|
|
125
|
+
LIST_RESP=$(api_call GET "/credentials")
|
|
126
|
+
CRED_ID=$(printf '%s' "$LIST_RESP" | jq -r --arg name "$NAME" '
|
|
127
|
+
.data[]? | select(.name == $name and .type == "google-oauth") | .id
|
|
128
|
+
' | head -n 1)
|
|
129
|
+
|
|
130
|
+
if [ -z "$CRED_ID" ]; then
|
|
131
|
+
AVAILABLE=$(printf '%s' "$LIST_RESP" | jq -r '
|
|
132
|
+
.data[]? | select(.type == "google-oauth") | .name
|
|
133
|
+
' | paste -sd ", " -)
|
|
134
|
+
error_exit "No google-oauth credential named '$NAME'. Available Google accounts: ${AVAILABLE:-none}. Use action=list to confirm."
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
# 2. Execute gmail-reader skill with the credential bound to 'gmail' slot
|
|
138
|
+
EXEC_BODY=$(jq -nc --arg cid "$CRED_ID" --arg max "$MAX" '{
|
|
139
|
+
agentId: "orchestrator",
|
|
140
|
+
roleId: "orchestrator",
|
|
141
|
+
userInput: $max,
|
|
142
|
+
credentialBindings: {gmail: $cid}
|
|
143
|
+
}')
|
|
144
|
+
RESP=$(api_call POST "/skills/skill-gmail-reader/execute" "$EXEC_BODY")
|
|
145
|
+
# Extract the stdout from the skill execution so the orchestrator sees
|
|
146
|
+
# the human-readable summary directly
|
|
147
|
+
printf '%s' "$RESP" | jq '
|
|
148
|
+
if .success == true then
|
|
149
|
+
{
|
|
150
|
+
credential: "'"$NAME"'",
|
|
151
|
+
credentialId: "'"$CRED_ID"'",
|
|
152
|
+
success: .data.success,
|
|
153
|
+
output: .data.output,
|
|
154
|
+
error: .data.error,
|
|
155
|
+
durationMs: .data.durationMs
|
|
156
|
+
}
|
|
157
|
+
else
|
|
158
|
+
{success: false, error: .error}
|
|
159
|
+
end
|
|
160
|
+
'
|
|
161
|
+
;;
|
|
162
|
+
|
|
163
|
+
*)
|
|
164
|
+
error_exit "Unknown action: '$ACTION'. Valid: list, start-google-oauth, complete-google-oauth, import-google, clear-gemini-cli, add-api-key, delete, read-gmail"
|
|
165
|
+
;;
|
|
166
|
+
esac
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Validation tests for credential-manager skill.
|
|
3
|
+
# Covers argument handling + param validation for each action. Actions that
|
|
4
|
+
# reach api_call are only exercised up to the point of validation (no live
|
|
5
|
+
# backend calls).
|
|
6
|
+
set -eo pipefail
|
|
7
|
+
|
|
8
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
9
|
+
EXECUTE="$SCRIPT_DIR/execute.sh"
|
|
10
|
+
PASS=0
|
|
11
|
+
FAIL=0
|
|
12
|
+
|
|
13
|
+
assert_contains() {
|
|
14
|
+
local test_name="$1" needle="$2" haystack="$3"
|
|
15
|
+
if printf '%s' "$haystack" | grep -q -- "$needle"; then
|
|
16
|
+
PASS=$((PASS + 1))
|
|
17
|
+
echo " ✓ ${test_name}"
|
|
18
|
+
else
|
|
19
|
+
FAIL=$((FAIL + 1))
|
|
20
|
+
echo " ✗ ${test_name}"
|
|
21
|
+
echo " expected to contain: ${needle}"
|
|
22
|
+
echo " got: ${haystack}"
|
|
23
|
+
fi
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
echo "=== credential-manager tests ==="
|
|
27
|
+
|
|
28
|
+
echo ""
|
|
29
|
+
echo "--- No input / missing action ---"
|
|
30
|
+
|
|
31
|
+
OUTPUT=$(bash "$EXECUTE" 2>&1) || true
|
|
32
|
+
assert_contains "No input rejected with usage hint" "Usage:" "$OUTPUT"
|
|
33
|
+
|
|
34
|
+
OUTPUT=$(bash "$EXECUTE" '{}' 2>&1) || true
|
|
35
|
+
assert_contains "Empty JSON → missing action error" "Missing required parameter: action" "$OUTPUT"
|
|
36
|
+
|
|
37
|
+
OUTPUT=$(bash "$EXECUTE" '{"action":""}' 2>&1) || true
|
|
38
|
+
assert_contains "Empty action → missing action error" "Missing required parameter: action" "$OUTPUT"
|
|
39
|
+
|
|
40
|
+
echo ""
|
|
41
|
+
echo "--- Unknown action ---"
|
|
42
|
+
|
|
43
|
+
OUTPUT=$(bash "$EXECUTE" '{"action":"does-not-exist"}' 2>&1) || true
|
|
44
|
+
assert_contains "Unknown action rejected" "Unknown action" "$OUTPUT"
|
|
45
|
+
assert_contains "Unknown action lists valid options" "list" "$OUTPUT"
|
|
46
|
+
|
|
47
|
+
echo ""
|
|
48
|
+
echo "--- import-google param validation ---"
|
|
49
|
+
|
|
50
|
+
OUTPUT=$(bash "$EXECUTE" '{"action":"import-google"}' 2>&1) || true
|
|
51
|
+
assert_contains "import-google without name rejected" "Missing required parameter: name" "$OUTPUT"
|
|
52
|
+
|
|
53
|
+
echo ""
|
|
54
|
+
echo "--- complete-google-oauth param validation ---"
|
|
55
|
+
|
|
56
|
+
OUTPUT=$(bash "$EXECUTE" '{"action":"complete-google-oauth"}' 2>&1) || true
|
|
57
|
+
assert_contains "complete without name rejected" "Missing required parameter: name" "$OUTPUT"
|
|
58
|
+
|
|
59
|
+
OUTPUT=$(bash "$EXECUTE" '{"action":"complete-google-oauth","name":"work"}' 2>&1) || true
|
|
60
|
+
assert_contains "complete without credentialsJson rejected" "credentialsJson is required" "$OUTPUT"
|
|
61
|
+
|
|
62
|
+
echo ""
|
|
63
|
+
echo "--- add-api-key param validation ---"
|
|
64
|
+
|
|
65
|
+
OUTPUT=$(bash "$EXECUTE" '{"action":"add-api-key"}' 2>&1) || true
|
|
66
|
+
assert_contains "add-api-key without name rejected" "Missing required parameter: name" "$OUTPUT"
|
|
67
|
+
|
|
68
|
+
OUTPUT=$(bash "$EXECUTE" '{"action":"add-api-key","name":"x"}' 2>&1) || true
|
|
69
|
+
assert_contains "add-api-key without provider rejected" "Missing required parameter: provider" "$OUTPUT"
|
|
70
|
+
|
|
71
|
+
OUTPUT=$(bash "$EXECUTE" '{"action":"add-api-key","name":"x","provider":"gemini"}' 2>&1) || true
|
|
72
|
+
assert_contains "add-api-key without value rejected" "Missing required parameter: value" "$OUTPUT"
|
|
73
|
+
|
|
74
|
+
echo ""
|
|
75
|
+
echo "--- delete param validation ---"
|
|
76
|
+
|
|
77
|
+
OUTPUT=$(bash "$EXECUTE" '{"action":"delete"}' 2>&1) || true
|
|
78
|
+
assert_contains "delete without id rejected" "Missing required parameter: id" "$OUTPUT"
|
|
79
|
+
|
|
80
|
+
echo ""
|
|
81
|
+
echo "--- read-gmail param validation ---"
|
|
82
|
+
|
|
83
|
+
OUTPUT=$(bash "$EXECUTE" '{"action":"read-gmail"}' 2>&1) || true
|
|
84
|
+
assert_contains "read-gmail without name rejected" "Missing required parameter: name" "$OUTPUT"
|
|
85
|
+
|
|
86
|
+
echo ""
|
|
87
|
+
echo "=== Results: ${PASS} passed, ${FAIL} failed ==="
|
|
88
|
+
[ $FAIL -eq 0 ]
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google OAuth Configuration
|
|
3
|
+
*
|
|
4
|
+
* Shared constants for the Google OAuth flows that piggyback on the Gemini
|
|
5
|
+
* CLI Workspace extension's published OAuth app. Defining these here lets
|
|
6
|
+
* the REST controller (URL-builder) and the helper (refresh client) stay in
|
|
7
|
+
* sync on client_id / redirect_uri / endpoints.
|
|
8
|
+
*
|
|
9
|
+
* These values come from the Gemini CLI Workspace extension's
|
|
10
|
+
* `workspace-server/src/utils/config.ts` — using the same client_id
|
|
11
|
+
* + redirect_uri lets us avoid the 7-day testing-mode grant expiry.
|
|
12
|
+
*
|
|
13
|
+
* @module config/oauth.config
|
|
14
|
+
*/
|
|
15
|
+
/** OAuth client_id for the Gemini CLI Workspace extension's published app. */
|
|
16
|
+
export declare const GOOGLE_OAUTH_CLIENT_ID = "338689075775-o75k922vn5fdl18qergr96rp8g63e4d7.apps.googleusercontent.com";
|
|
17
|
+
/** Redirect URI the Gemini CLI Workspace cloud function is registered for. */
|
|
18
|
+
export declare const GOOGLE_OAUTH_REDIRECT_URI = "https://google-workspace-extension.geminicli.com";
|
|
19
|
+
/** Base URL of Google's OAuth 2.0 authorization endpoint. */
|
|
20
|
+
export declare const GOOGLE_OAUTH_AUTH_BASE = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
21
|
+
/** Cloud Function base URL where the extension's `/refreshToken` lives. */
|
|
22
|
+
export declare const GEMINI_CLI_CLOUD_FUNCTION_URL = "https://google-workspace-extension.geminicli.com";
|
|
23
|
+
/** Path on the cloud function used for token refresh calls. */
|
|
24
|
+
export declare const GEMINI_CLI_REFRESH_PATH = "/refreshToken";
|
|
25
|
+
/** Google's userinfo endpoint — used to resolve an OAuth token's account email. */
|
|
26
|
+
export declare const GOOGLE_USERINFO_ENDPOINT = "https://www.googleapis.com/oauth2/v3/userinfo";
|
|
27
|
+
/**
|
|
28
|
+
* Default scope set for a broad Workspace grant — covers the common Gmail,
|
|
29
|
+
* Drive, Docs, Calendar, and Photos read paths used by marketplace skills.
|
|
30
|
+
* Callers of `/oauth/google/start` may override via the request body.
|
|
31
|
+
*/
|
|
32
|
+
export declare const DEFAULT_GOOGLE_SCOPES: readonly string[];
|
|
33
|
+
//# sourceMappingURL=oauth.config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.config.d.ts","sourceRoot":"","sources":["../../../../../backend/src/config/oauth.config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,sBAAsB,6EACyC,CAAC;AAE7E,8EAA8E;AAC9E,eAAO,MAAM,yBAAyB,qDACc,CAAC;AAErD,6DAA6D;AAC7D,eAAO,MAAM,sBAAsB,iDACa,CAAC;AAEjD,2EAA2E;AAC3E,eAAO,MAAM,6BAA6B,qDACU,CAAC;AAErD,+DAA+D;AAC/D,eAAO,MAAM,uBAAuB,kBAAkB,CAAC;AAEvD,mFAAmF;AACnF,eAAO,MAAM,wBAAwB,kDACY,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,SAAS,MAAM,EAYlD,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google OAuth Configuration
|
|
3
|
+
*
|
|
4
|
+
* Shared constants for the Google OAuth flows that piggyback on the Gemini
|
|
5
|
+
* CLI Workspace extension's published OAuth app. Defining these here lets
|
|
6
|
+
* the REST controller (URL-builder) and the helper (refresh client) stay in
|
|
7
|
+
* sync on client_id / redirect_uri / endpoints.
|
|
8
|
+
*
|
|
9
|
+
* These values come from the Gemini CLI Workspace extension's
|
|
10
|
+
* `workspace-server/src/utils/config.ts` — using the same client_id
|
|
11
|
+
* + redirect_uri lets us avoid the 7-day testing-mode grant expiry.
|
|
12
|
+
*
|
|
13
|
+
* @module config/oauth.config
|
|
14
|
+
*/
|
|
15
|
+
/** OAuth client_id for the Gemini CLI Workspace extension's published app. */
|
|
16
|
+
export const GOOGLE_OAUTH_CLIENT_ID = '338689075775-o75k922vn5fdl18qergr96rp8g63e4d7.apps.googleusercontent.com';
|
|
17
|
+
/** Redirect URI the Gemini CLI Workspace cloud function is registered for. */
|
|
18
|
+
export const GOOGLE_OAUTH_REDIRECT_URI = 'https://google-workspace-extension.geminicli.com';
|
|
19
|
+
/** Base URL of Google's OAuth 2.0 authorization endpoint. */
|
|
20
|
+
export const GOOGLE_OAUTH_AUTH_BASE = 'https://accounts.google.com/o/oauth2/v2/auth';
|
|
21
|
+
/** Cloud Function base URL where the extension's `/refreshToken` lives. */
|
|
22
|
+
export const GEMINI_CLI_CLOUD_FUNCTION_URL = 'https://google-workspace-extension.geminicli.com';
|
|
23
|
+
/** Path on the cloud function used for token refresh calls. */
|
|
24
|
+
export const GEMINI_CLI_REFRESH_PATH = '/refreshToken';
|
|
25
|
+
/** Google's userinfo endpoint — used to resolve an OAuth token's account email. */
|
|
26
|
+
export const GOOGLE_USERINFO_ENDPOINT = 'https://www.googleapis.com/oauth2/v3/userinfo';
|
|
27
|
+
/**
|
|
28
|
+
* Default scope set for a broad Workspace grant — covers the common Gmail,
|
|
29
|
+
* Drive, Docs, Calendar, and Photos read paths used by marketplace skills.
|
|
30
|
+
* Callers of `/oauth/google/start` may override via the request body.
|
|
31
|
+
*/
|
|
32
|
+
export const DEFAULT_GOOGLE_SCOPES = [
|
|
33
|
+
'openid',
|
|
34
|
+
'https://www.googleapis.com/auth/userinfo.email',
|
|
35
|
+
'https://www.googleapis.com/auth/userinfo.profile',
|
|
36
|
+
'https://www.googleapis.com/auth/gmail.readonly',
|
|
37
|
+
'https://www.googleapis.com/auth/gmail.send',
|
|
38
|
+
'https://www.googleapis.com/auth/drive.readonly',
|
|
39
|
+
'https://www.googleapis.com/auth/drive.file',
|
|
40
|
+
'https://www.googleapis.com/auth/documents.readonly',
|
|
41
|
+
'https://www.googleapis.com/auth/calendar.readonly',
|
|
42
|
+
'https://www.googleapis.com/auth/calendar.events',
|
|
43
|
+
'https://www.googleapis.com/auth/photoslibrary.readonly',
|
|
44
|
+
];
|
|
45
|
+
//# sourceMappingURL=oauth.config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.config.js","sourceRoot":"","sources":["../../../../../backend/src/config/oauth.config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,8EAA8E;AAC9E,MAAM,CAAC,MAAM,sBAAsB,GACjC,0EAA0E,CAAC;AAE7E,8EAA8E;AAC9E,MAAM,CAAC,MAAM,yBAAyB,GACpC,kDAAkD,CAAC;AAErD,6DAA6D;AAC7D,MAAM,CAAC,MAAM,sBAAsB,GACjC,8CAA8C,CAAC;AAEjD,2EAA2E;AAC3E,MAAM,CAAC,MAAM,6BAA6B,GACxC,kDAAkD,CAAC;AAErD,+DAA+D;AAC/D,MAAM,CAAC,MAAM,uBAAuB,GAAG,eAAe,CAAC;AAEvD,mFAAmF;AACnF,MAAM,CAAC,MAAM,wBAAwB,GACnC,+CAA+C,CAAC;AAElD;;;;GAIG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAsB;IACtD,QAAQ;IACR,gDAAgD;IAChD,kDAAkD;IAClD,gDAAgD;IAChD,4CAA4C;IAC5C,gDAAgD;IAChD,4CAA4C;IAC5C,oDAAoD;IACpD,mDAAmD;IACnD,iDAAiD;IACjD,wDAAwD;CACzD,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credentials REST Controller
|
|
3
|
+
*
|
|
4
|
+
* Exposes workspace credential management over REST so the frontend (and
|
|
5
|
+
* Cloud portal) can list, add, rename, delete, and OAuth-import credentials.
|
|
6
|
+
*
|
|
7
|
+
* All endpoints return `{ success, data?, error? }` matching the rest of
|
|
8
|
+
* the Crewly API surface. Secret values (token payloads, API keys) are
|
|
9
|
+
* never returned — only registry metadata.
|
|
10
|
+
*
|
|
11
|
+
* @module controllers/credentials/credentials.controller
|
|
12
|
+
*/
|
|
13
|
+
import type { Request, Response, NextFunction } from 'express';
|
|
14
|
+
/** Reset the helper singleton — for tests only. */
|
|
15
|
+
export declare function _resetGeminiHelperForTesting(): void;
|
|
16
|
+
/**
|
|
17
|
+
* GET /api/credentials — list all credential metadata (never values).
|
|
18
|
+
*/
|
|
19
|
+
export declare function listCredentials(_req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* GET /api/credentials/:id — metadata for a single credential.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getCredentialById(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* POST /api/credentials/api-key — add an API key credential.
|
|
26
|
+
* Body: { name, provider, value }
|
|
27
|
+
*/
|
|
28
|
+
export declare function addApiKey(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* PATCH /api/credentials/:id — update metadata (name, status).
|
|
31
|
+
* Body: { name?, status? }
|
|
32
|
+
*/
|
|
33
|
+
export declare function updateCredentialHandler(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* DELETE /api/credentials/:id — delete credential (registry entry + .enc file).
|
|
36
|
+
*/
|
|
37
|
+
export declare function deleteCredentialHandler(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* POST /api/credentials/oauth/import-gemini-cli — capture current extension
|
|
40
|
+
* login into a new credential.
|
|
41
|
+
* Body: { name }
|
|
42
|
+
*
|
|
43
|
+
* Precondition: the user has run
|
|
44
|
+
* `GEMINI_CLI_WORKSPACE_FORCE_FILE_STORAGE=true gemini`
|
|
45
|
+
* and signed in via the workspace extension.
|
|
46
|
+
*/
|
|
47
|
+
export declare function importOAuthFromGeminiCli(req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* POST /api/credentials/oauth/gemini-cli/clear-extension-file —
|
|
50
|
+
* delete the extension's cached token file so the next extension login
|
|
51
|
+
* captures a different account.
|
|
52
|
+
*/
|
|
53
|
+
export declare function clearGeminiCliExtensionFile(_req: Request, res: Response, next: NextFunction): Promise<void>;
|
|
54
|
+
//# sourceMappingURL=credentials.controller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials.controller.d.ts","sourceRoot":"","sources":["../../../../../../backend/src/controllers/credentials/credentials.controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA0C/D,mDAAmD;AACnD,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD;AAMD;;GAEG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAkDf;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAYf;AAED;;;;;;;;GAQG;AACH,wBAAsB,wBAAwB,CAC5C,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CA8Bf;AAED;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,IAAI,EAAE,OAAO,EACb,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,CAAC,CAQf"}
|