@fourier-labs/harbour-contracts 0.77.0 → 0.79.0

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.
Files changed (45) hide show
  1. package/README.md +3 -3
  2. package/contract-release.json +31 -25
  3. package/dist/gen-ts/app-integrations-declaration.d.ts +11 -2
  4. package/dist/gen-ts/app-sign-in.d.ts +9 -0
  5. package/dist/gen-ts/app-sign-in.js +3 -0
  6. package/dist/gen-ts/contract-release.d.ts +6 -6
  7. package/dist/gen-ts/contract-release.js +6 -6
  8. package/dist/gen-ts/data-grant-v2.d.ts +5 -5
  9. package/dist/gen-ts/deployment-app-registration.d.ts +8 -2
  10. package/dist/gen-ts/external-sign-in.d.ts +29 -0
  11. package/dist/gen-ts/external-sign-in.js +3 -0
  12. package/dist/gen-ts/identity-context.d.ts +18 -0
  13. package/dist/gen-ts/identity-context.js +3 -0
  14. package/dist/gen-ts/index.d.ts +3 -0
  15. package/dist/gen-ts/index.js +3 -0
  16. package/dist/gen-ts/integration-execute-input-rules.d.ts +202 -0
  17. package/dist/gen-ts/integration-execute-input-rules.js +88 -2
  18. package/dist/gen-ts/integration-execute-request.d.ts +52 -6
  19. package/dist/gen-ts/integration-execute-result.d.ts +90 -2
  20. package/dist/gen-ts/integration-operations.d.ts +63 -0
  21. package/dist/gen-ts/integration-operations.js +81 -0
  22. package/dist/gen-ts/saas-connection.d.ts +11 -11
  23. package/gen-ts/app-integrations-declaration.ts +11 -2
  24. package/gen-ts/app-sign-in.ts +12 -0
  25. package/gen-ts/contract-release.ts +6 -6
  26. package/gen-ts/data-grant-v2.ts +13 -4
  27. package/gen-ts/deployment-app-registration.ts +8 -2
  28. package/gen-ts/external-sign-in.ts +32 -0
  29. package/gen-ts/identity-context.ts +21 -0
  30. package/gen-ts/index.ts +3 -0
  31. package/gen-ts/integration-execute-input-rules.ts +90 -4
  32. package/gen-ts/integration-execute-request.ts +60 -5
  33. package/gen-ts/integration-execute-result.ts +90 -2
  34. package/gen-ts/integration-operations.ts +81 -0
  35. package/gen-ts/saas-connection.ts +19 -10
  36. package/package.json +1 -1
  37. package/schema/app-integrations-declaration.schema.json +193 -3
  38. package/schema/app-sign-in.schema.json +51 -0
  39. package/schema/data-grant-v2.schema.json +4 -4
  40. package/schema/deployment-app-registration.schema.json +5 -2
  41. package/schema/external-sign-in.schema.json +120 -0
  42. package/schema/identity-context.schema.json +141 -0
  43. package/schema/integration-execute-request.schema.json +497 -7
  44. package/schema/integration-execute-result.schema.json +345 -4
  45. package/schema/saas-connection.schema.json +27 -10
@@ -205,6 +205,87 @@ export const IntegrationOperations = {
205
205
  "declaredMode": false,
206
206
  "idempotencyKey": false
207
207
  },
208
+ "sharepoint.list.list": {
209
+ "kind": "saas",
210
+ "identities": [
211
+ "user"
212
+ ],
213
+ "readOnly": true,
214
+ "declaredMode": false,
215
+ "idempotencyKey": false
216
+ },
217
+ "sharepoint.item.list": {
218
+ "kind": "saas",
219
+ "identities": [
220
+ "user"
221
+ ],
222
+ "readOnly": true,
223
+ "declaredMode": false,
224
+ "idempotencyKey": false
225
+ },
226
+ "sharepoint.item.create": {
227
+ "kind": "saas",
228
+ "identities": [
229
+ "user"
230
+ ],
231
+ "readOnly": false,
232
+ "declaredMode": false,
233
+ "idempotencyKey": true
234
+ },
235
+ "sharepoint.item.update": {
236
+ "kind": "saas",
237
+ "identities": [
238
+ "user"
239
+ ],
240
+ "readOnly": false,
241
+ "declaredMode": false,
242
+ "idempotencyKey": false
243
+ },
244
+ "sharepoint.drive.list": {
245
+ "kind": "saas",
246
+ "identities": [
247
+ "user"
248
+ ],
249
+ "readOnly": true,
250
+ "declaredMode": false,
251
+ "idempotencyKey": false
252
+ },
253
+ "sharepoint.file.list": {
254
+ "kind": "saas",
255
+ "identities": [
256
+ "user"
257
+ ],
258
+ "readOnly": true,
259
+ "declaredMode": false,
260
+ "idempotencyKey": false
261
+ },
262
+ "sharepoint.file.search": {
263
+ "kind": "saas",
264
+ "identities": [
265
+ "user"
266
+ ],
267
+ "readOnly": true,
268
+ "declaredMode": false,
269
+ "idempotencyKey": false
270
+ },
271
+ "sharepoint.file.read": {
272
+ "kind": "saas",
273
+ "identities": [
274
+ "user"
275
+ ],
276
+ "readOnly": true,
277
+ "declaredMode": false,
278
+ "idempotencyKey": false
279
+ },
280
+ "sharepoint.file.upload": {
281
+ "kind": "saas",
282
+ "identities": [
283
+ "user"
284
+ ],
285
+ "readOnly": false,
286
+ "declaredMode": false,
287
+ "idempotencyKey": true
288
+ },
208
289
  "warehouse.view.read": {
209
290
  "kind": "database",
210
291
  "identities": [
@@ -2,9 +2,9 @@
2
2
  // Code generated by tools/gen/gen.mjs from schema/*.json. DO NOT EDIT.
3
3
 
4
4
  /**
5
- * Slack carries an installation and a channel map; Gmail is user-consent only; Basecamp is user-consent only with an IT-pinned account and a project map in `channels`.
5
+ * Slack carries an installation and a channel map; Gmail is user-consent only; Basecamp is user-consent only with an IT-pinned account and a project map in `channels`; SharePoint (0.78.0) is user-consent only, pinned to the company's Microsoft 365 tenant in `account`, with a site map in `channels`.
6
6
  */
7
- export type SaasProvider = 'slack' | 'gmail' | 'basecamp';
7
+ export type SaasProvider = 'slack' | 'gmail' | 'basecamp' | 'sharepoint';
8
8
  /**
9
9
  * DISABLED stops every app call immediately (details.code CONNECTION_DISABLED).
10
10
  */
@@ -27,7 +27,7 @@ export type ExternalRecipientMode = 'block' | 'allowlist' | 'allow';
27
27
  export type InstallationName = string;
28
28
 
29
29
  /**
30
- * Tenant-wide SaaS connection record (control table sk SAASCONN#<sourceId>, same tenant partition as database sources; alias uniqueness is enforced across both). One connection per tenant and provider: a single bot installation of the platform-owned provider app and a single logical channel map shared by every app environment (grants, requests and user consent links stay per environment). A Gmail connection has neither installation nor channels: user consent is the only step and its one resource is the fixed `inbox` alias. A Basecamp connection (0.76.0, ADR 0022) has no installation either: IT pins the company's Basecamp `account` (chosen from the accounts IT's own Basecamp sign-in belongs to) and maps project aliases to project ids in `channels`; basecamp.project.list runs on the fixed `account` alias. Contains references, never secrets: installation tokens live under their own token records. The pre-T25 per-environment shape (`clientId`, `clientSecretRef`, `environments`, `installations`) is deprecated: the control plane normalises such a stored record on read and never writes it.
30
+ * Tenant-wide SaaS connection record (control table sk SAASCONN#<sourceId>, same tenant partition as database sources; alias uniqueness is enforced across both). One connection per tenant and provider: a single bot installation of the platform-owned provider app and a single logical channel map shared by every app environment (grants, requests and user consent links stay per environment). A Gmail connection has neither installation nor channels: user consent is the only step and its one resource is the fixed `inbox` alias. A Basecamp connection (0.76.0, ADR 0022) has no installation either: IT pins the company's Basecamp `account` (chosen from the accounts IT's own Basecamp sign-in belongs to) and maps project aliases to project ids in `channels`; basecamp.project.list runs on the fixed `account` alias. A SharePoint connection (0.78.0, ADR 0024) is shaped the same way: IT pins the company's Microsoft 365 tenant in `account` (the Entra tenant id and the organisation's display name, from IT's own Microsoft sign-in) and maps site aliases to Microsoft Graph site ids (`hostname,siteCollectionGuid,webGuid`) in `channels`; every sharepoint.* operation runs on a site alias. Contains references, never secrets: installation tokens live under their own token records. The pre-T25 per-environment shape (`clientId`, `clientSecretRef`, `environments`, `installations`) is deprecated: the control plane normalises such a stored record on read and never writes it.
31
31
  */
32
32
  export interface SaasConnection {
33
33
  schema: 'harbour.saas-connection/1.0';
@@ -47,19 +47,19 @@ export interface SaasConnection {
47
47
  installation?: SaasInstallation;
48
48
  account?: BasecampAccount;
49
49
  /**
50
- * Logical alias → provider resource id: a Slack channel id or a Basecamp project id. Always empty for Gmail.
50
+ * Logical alias → provider resource id: a Slack channel id, a Basecamp project id or a SharePoint site id. Always empty for Gmail.
51
51
  */
52
52
  channels: {
53
53
  /**
54
- * A Slack channel id (public, non-archived) or a Basecamp project id (digits).
54
+ * A Slack channel id (public, non-archived), a Basecamp project id (digits) or a SharePoint site id (0.78.0: the Microsoft Graph composite `hostname,siteCollectionGuid,webGuid`).
55
55
  */
56
56
  [k: string]: string;
57
57
  };
58
58
  /**
59
- * Operations IT allows apps to request on this connection: the provider's own SaaS operations (Slack: slack.channel.history, slack.message.post, slack.message.update, slack.message.delete, slack.dm.send, slack.user.lookup; Gmail: gmail.thread.list, gmail.thread.read, gmail.message.read, gmail.message.send, gmail.attachment.read; Basecamp (0.76.0): basecamp.project.list, basecamp.todolist.list, basecamp.todo.list, basecamp.todo.create, basecamp.todo.complete, basecamp.message.list, basecamp.message.post, basecamp.comment.list, basecamp.comment.post, basecamp.campfire.post, basecamp.people.list). Never warehouse.view.read.
59
+ * Operations IT allows apps to request on this connection: the provider's own SaaS operations (Slack: slack.channel.history, slack.message.post, slack.message.update, slack.message.delete, slack.dm.send, slack.user.lookup; Gmail: gmail.thread.list, gmail.thread.read, gmail.message.read, gmail.message.send, gmail.attachment.read; Basecamp (0.76.0): basecamp.project.list, basecamp.todolist.list, basecamp.todo.list, basecamp.todo.create, basecamp.todo.complete, basecamp.message.list, basecamp.message.post, basecamp.comment.list, basecamp.comment.post, basecamp.campfire.post, basecamp.people.list; SharePoint (0.78.0): sharepoint.list.list, sharepoint.item.list, sharepoint.item.create, sharepoint.item.update, sharepoint.drive.list, sharepoint.file.list, sharepoint.file.search, sharepoint.file.read, sharepoint.file.upload). Never warehouse.view.read.
60
60
  *
61
61
  * @minItems 1
62
- * @maxItems 22
62
+ * @maxItems 31
63
63
  */
64
64
  operations: (
65
65
  | 'slack.channel.history'
@@ -84,6 +84,15 @@ export interface SaasConnection {
84
84
  | 'basecamp.comment.post'
85
85
  | 'basecamp.campfire.post'
86
86
  | 'basecamp.people.list'
87
+ | 'sharepoint.list.list'
88
+ | 'sharepoint.item.list'
89
+ | 'sharepoint.item.create'
90
+ | 'sharepoint.item.update'
91
+ | 'sharepoint.drive.list'
92
+ | 'sharepoint.file.list'
93
+ | 'sharepoint.file.search'
94
+ | 'sharepoint.file.read'
95
+ | 'sharepoint.file.upload'
87
96
  | 'warehouse.view.read'
88
97
  | 'service.request'
89
98
  )[];
@@ -151,15 +160,15 @@ export interface SaasInstallation {
151
160
  botName?: string;
152
161
  }
153
162
  /**
154
- * The pinned Basecamp account (0.76.0, Basecamp only): the one account, among those IT's own Basecamp sign-in belongs to, that every user token on this connection must also belong to and that every project id in `channels` lives in. Absent until IT chooses it; governance refuses every basecamp.* call until then.
163
+ * The pinned provider account (0.76.0, Basecamp; 0.78.0, SharePoint — the name keeps its 0.76.0 spelling so consumers need not move): the one account, among those IT's own provider sign-in belongs to, that every user token on this connection must also belong to and that every resource id in `channels` lives in. For Basecamp the account (digits); for SharePoint the Microsoft 365 tenant (the Entra tenant GUID). Absent until IT chooses it; governance refuses every basecamp.* and sharepoint.* call until then.
155
164
  */
156
165
  export interface BasecampAccount {
157
166
  /**
158
- * The Basecamp account id, the first path segment of the API base URL.
167
+ * The Basecamp account id (digits, the first path segment of the API base URL) or the Microsoft Entra tenant id (a GUID, the `tid` claim).
159
168
  */
160
169
  id: string;
161
170
  /**
162
- * The account's name as Basecamp shows it, for IT to recognise.
171
+ * The account's name as the provider shows it (a Basecamp account name, a Microsoft 365 organisation display name), for IT to recognise.
163
172
  */
164
173
  name: string;
165
174
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fourier-labs/harbour-contracts",
3
- "version": "0.77.0",
3
+ "version": "0.79.0",
4
4
  "description": "Single source of truth for every data shape that crosses a boundary between Isomorph components.",
5
5
  "license": "UNLICENSED",
6
6
  "private": false,
@@ -2,7 +2,7 @@
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "https://schemas.harbour.dev/app-integrations-declaration.schema.json",
4
4
  "title": "AppIntegrationsDeclaration",
5
- "description": "Committed `.isomorph/integrations.json`: the app's declared use of tenant-wide integration connections. Keys are logical connection aliases (the governance sourceId); resources are logical names (Slack channel alias, warehouse view name), never IDs, tokens or URLs. The operation set is closed (twenty-four operations since 0.76.0, ADR 0018 and ADR 0022). Each operation carries a fixed identity mode \u2014 slack.dm.send=app, slack.user.lookup=app, every gmail.* operation=user, every basecamp.* operation=user, warehouse.view.read=app, service.request=app \u2014 except the declared-mode Slack operations (slack.message.post, and since 0.71.0 slack.channel.history, slack.message.update and slack.message.delete), whose mode the app DECLARES: `app` acts as the company's Slack app (the one audited bot identity; a post goes out under the IT-approved per-app display name when the connection declares `presentation`), `user` acts as the signed-in person after their own consent (reads what they can read, edits what they wrote). The declared mode is the one the app requests access for; an app may hold approved grants for both modes after two requests, and each declared-mode call names which approved mode it runs under (`mode` on the execute request, 0.55.0) \u2014 a mode IT did not approve is refused, never swapped for the other. A `saas` connection may declare only the Slack, Gmail and Basecamp operations and a `database` connection only warehouse.view.read; `presentation` is a `saas` connection's optional per-app display name and icon for app-mode Slack posts, shown to IT at approval time and applied only from the approved grant. Gmail is user-mode only (reads, one send); its single resource is the fixed `inbox` alias. Basecamp (0.76.0, ADR 0022) is user-mode only too: basecamp.project.list runs on the fixed `account` alias (the company's pinned Basecamp account) and every other basecamp.* operation on a project alias IT mapped in the connection's `channels` map, so Basecamp itself refuses an id outside that project. slack.dm.send and slack.user.lookup address people by email rather than a channel, so their single resource is the fixed `workspace` alias (the connection's installed workspace), the way Gmail's is `inbox`. This file also owns the shared IntegrationOperation / IntegrationIdentityMode / IntegrationEnvironment / IntegrationConnectionKind / IntegrationPresentation definitions referenced by the other integration schemas.",
5
+ "description": "Committed `.isomorph/integrations.json`: the app's declared use of tenant-wide integration connections. Keys are logical connection aliases (the governance sourceId); resources are logical names (Slack channel alias, warehouse view name), never IDs, tokens or URLs. The operation set is closed (thirty-three operations since 0.78.0, ADR 0018, ADR 0022 and ADR 0024). Each operation carries a fixed identity mode \u2014 slack.dm.send=app, slack.user.lookup=app, every gmail.* operation=user, every basecamp.* operation=user, every sharepoint.* operation=user, warehouse.view.read=app, service.request=app \u2014 except the declared-mode Slack operations (slack.message.post, and since 0.71.0 slack.channel.history, slack.message.update and slack.message.delete), whose mode the app DECLARES: `app` acts as the company's Slack app (the one audited bot identity; a post goes out under the IT-approved per-app display name when the connection declares `presentation`), `user` acts as the signed-in person after their own consent (reads what they can read, edits what they wrote). The declared mode is the one the app requests access for; an app may hold approved grants for both modes after two requests, and each declared-mode call names which approved mode it runs under (`mode` on the execute request, 0.55.0) \u2014 a mode IT did not approve is refused, never swapped for the other. A `saas` connection may declare only the Slack, Gmail, Basecamp and SharePoint operations and a `database` connection only warehouse.view.read; `presentation` is a `saas` connection's optional per-app display name and icon for app-mode Slack posts, shown to IT at approval time and applied only from the approved grant. Gmail is user-mode only (reads, one send); its single resource is the fixed `inbox` alias. Basecamp (0.76.0, ADR 0022) is user-mode only too: basecamp.project.list runs on the fixed `account` alias (the company's pinned Basecamp account) and every other basecamp.* operation on a project alias IT mapped in the connection's `channels` map, so Basecamp itself refuses an id outside that project. SharePoint (0.78.0, ADR 0024) is user-mode only as well: every sharepoint.* operation runs on a site alias IT mapped in the connection's `channels` map (a Microsoft Graph site id), so Graph itself refuses a list, item or file outside that site. slack.dm.send and slack.user.lookup address people by email rather than a channel, so their single resource is the fixed `workspace` alias (the connection's installed workspace), the way Gmail's is `inbox`. This file also owns the shared IntegrationOperation / IntegrationIdentityMode / IntegrationEnvironment / IntegrationConnectionKind / IntegrationPresentation definitions referenced by the other integration schemas.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "required": [
@@ -37,6 +37,11 @@
37
37
  "pattern": "^[0-9]{1,20}$",
38
38
  "description": "A Basecamp id (0.76.0): an account, project, to-do list, to-do, recording or person, as a string of 1..20 digits \u2014 how every basecamp.* result names one and every basecamp.* input takes one back."
39
39
  },
40
+ "GraphId": {
41
+ "type": "string",
42
+ "pattern": "^[A-Za-z0-9!._,=-]{1,256}$",
43
+ "description": "A Microsoft Graph id (0.78.0): a SharePoint list (a GUID), list item (digits), drive (`b!...`) or drive item, as Graph names it \u2014 opaque, 1..256 characters of letters, digits and `!._,=-`. How every sharepoint.* result names one and every sharepoint.* input takes one back."
44
+ },
40
45
  "IntegrationConnectionKind": {
41
46
  "type": "string",
42
47
  "enum": [
@@ -70,10 +75,19 @@
70
75
  "basecamp.comment.post",
71
76
  "basecamp.campfire.post",
72
77
  "basecamp.people.list",
78
+ "sharepoint.list.list",
79
+ "sharepoint.item.list",
80
+ "sharepoint.item.create",
81
+ "sharepoint.item.update",
82
+ "sharepoint.drive.list",
83
+ "sharepoint.file.list",
84
+ "sharepoint.file.search",
85
+ "sharepoint.file.read",
86
+ "sharepoint.file.upload",
73
87
  "warehouse.view.read",
74
88
  "service.request"
75
89
  ],
76
- "description": "Closed operation set. Extending it is a contracts change. 0.76.0 (ADR 0022) adds the eleven Basecamp operations, every one user mode only like gmail.*: basecamp.project.list (the projects of the company's pinned Basecamp account; its resource is the fixed `account` alias), and on one mapped project (the resource is a project alias, a key of the connection's `channels` map) basecamp.todolist.list, basecamp.todo.list, basecamp.todo.create (a receipted write: explicit action, idempotencyKey), basecamp.todo.complete (idempotent at Basecamp, no key), basecamp.message.list, basecamp.message.post, basecamp.comment.list, basecamp.comment.post, basecamp.campfire.post (the three posts are receipted writes) and basecamp.people.list. gmail.message.send (0.50.0) sends one email as the signed-in person: a send like slack.message.post (explicit Send, idempotencyKey, write receipt) under user identity; since 0.71.0 it may carry an HTML body and attachments. slack.message.post (0.53.0) runs in the mode the app declares: app (the company's Slack app, under the IT-approved per-app name) or user (the signed-in person, after their consent); since 0.55.0 each call names which of the approved modes it runs under. 0.71.0 (ADR 0018) adds slack.message.update and slack.message.delete (declared mode, like post), slack.dm.send (app mode: a direct message to 1..8 workspace members named by email), slack.user.lookup (app mode: email to Slack user id), gmail.thread.read (every message of one thread) and gmail.attachment.read (one attachment's bytes), and lets slack.channel.history run in app mode as well as user mode."
90
+ "description": "Closed operation set. Extending it is a contracts change. 0.78.0 (ADR 0024) adds the nine SharePoint operations, every one user mode only on a site alias (a key of the connection's `channels` map, holding a Microsoft Graph site id): sharepoint.list.list, sharepoint.item.list, sharepoint.item.create (a receipted write: explicit action, idempotencyKey), sharepoint.item.update (a PATCH, idempotent at Graph, no key), sharepoint.drive.list, sharepoint.file.list, sharepoint.file.search, sharepoint.file.read and sharepoint.file.upload (a receipted write). 0.76.0 (ADR 0022) adds the eleven Basecamp operations, every one user mode only like gmail.*: basecamp.project.list (the projects of the company's pinned Basecamp account; its resource is the fixed `account` alias), and on one mapped project (the resource is a project alias, a key of the connection's `channels` map) basecamp.todolist.list, basecamp.todo.list, basecamp.todo.create (a receipted write: explicit action, idempotencyKey), basecamp.todo.complete (idempotent at Basecamp, no key), basecamp.message.list, basecamp.message.post, basecamp.comment.list, basecamp.comment.post, basecamp.campfire.post (the three posts are receipted writes) and basecamp.people.list. gmail.message.send (0.50.0) sends one email as the signed-in person: a send like slack.message.post (explicit Send, idempotencyKey, write receipt) under user identity; since 0.71.0 it may carry an HTML body and attachments. slack.message.post (0.53.0) runs in the mode the app declares: app (the company's Slack app, under the IT-approved per-app name) or user (the signed-in person, after their consent); since 0.55.0 each call names which of the approved modes it runs under. 0.71.0 (ADR 0018) adds slack.message.update and slack.message.delete (declared mode, like post), slack.dm.send (app mode: a direct message to 1..8 workspace members named by email), slack.user.lookup (app mode: email to Slack user id), gmail.thread.read (every message of one thread) and gmail.attachment.read (one attachment's bytes), and lets slack.channel.history run in app mode as well as user mode."
77
91
  },
78
92
  "IntegrationIdentityMode": {
79
93
  "type": "string",
@@ -163,7 +177,7 @@
163
177
  "identity",
164
178
  "resources"
165
179
  ],
166
- "description": "Every gmail.* operation (resource: the fixed `inbox` alias) and, since 0.76.0, every basecamp.* operation (resource: a project alias from the connection's `channels` map, or the fixed `account` alias for basecamp.project.list): user mode only — the app acts as the signed-in person after their own consent.",
180
+ "description": "Every gmail.* operation (resource: the fixed `inbox` alias), since 0.76.0 every basecamp.* operation (resource: a project alias from the connection's `channels` map, or the fixed `account` alias for basecamp.project.list) and since 0.78.0 every sharepoint.* operation (resource: a site alias from the connection's `channels` map): user mode only — the app acts as the signed-in person after their own consent.",
167
181
  "properties": {
168
182
  "identity": {
169
183
  "type": "string",
@@ -320,6 +334,33 @@
320
334
  "basecamp.people.list": {
321
335
  "$ref": "#/definitions/UserModeChannelOperation"
322
336
  },
337
+ "sharepoint.list.list": {
338
+ "$ref": "#/definitions/UserModeChannelOperation"
339
+ },
340
+ "sharepoint.item.list": {
341
+ "$ref": "#/definitions/UserModeChannelOperation"
342
+ },
343
+ "sharepoint.item.create": {
344
+ "$ref": "#/definitions/UserModeChannelOperation"
345
+ },
346
+ "sharepoint.item.update": {
347
+ "$ref": "#/definitions/UserModeChannelOperation"
348
+ },
349
+ "sharepoint.drive.list": {
350
+ "$ref": "#/definitions/UserModeChannelOperation"
351
+ },
352
+ "sharepoint.file.list": {
353
+ "$ref": "#/definitions/UserModeChannelOperation"
354
+ },
355
+ "sharepoint.file.search": {
356
+ "$ref": "#/definitions/UserModeChannelOperation"
357
+ },
358
+ "sharepoint.file.read": {
359
+ "$ref": "#/definitions/UserModeChannelOperation"
360
+ },
361
+ "sharepoint.file.upload": {
362
+ "$ref": "#/definitions/UserModeChannelOperation"
363
+ },
323
364
  "warehouse.view.read": {
324
365
  "$ref": "#/definitions/AppModeViewOperation"
325
366
  },
@@ -482,6 +523,51 @@
482
523
  "basecamp.people.list"
483
524
  ]
484
525
  },
526
+ {
527
+ "required": [
528
+ "sharepoint.list.list"
529
+ ]
530
+ },
531
+ {
532
+ "required": [
533
+ "sharepoint.item.list"
534
+ ]
535
+ },
536
+ {
537
+ "required": [
538
+ "sharepoint.item.create"
539
+ ]
540
+ },
541
+ {
542
+ "required": [
543
+ "sharepoint.item.update"
544
+ ]
545
+ },
546
+ {
547
+ "required": [
548
+ "sharepoint.drive.list"
549
+ ]
550
+ },
551
+ {
552
+ "required": [
553
+ "sharepoint.file.list"
554
+ ]
555
+ },
556
+ {
557
+ "required": [
558
+ "sharepoint.file.search"
559
+ ]
560
+ },
561
+ {
562
+ "required": [
563
+ "sharepoint.file.read"
564
+ ]
565
+ },
566
+ {
567
+ "required": [
568
+ "sharepoint.file.upload"
569
+ ]
570
+ },
485
571
  {
486
572
  "required": [
487
573
  "service.request"
@@ -621,6 +707,51 @@
621
707
  "basecamp.people.list"
622
708
  ]
623
709
  },
710
+ {
711
+ "required": [
712
+ "sharepoint.list.list"
713
+ ]
714
+ },
715
+ {
716
+ "required": [
717
+ "sharepoint.item.list"
718
+ ]
719
+ },
720
+ {
721
+ "required": [
722
+ "sharepoint.item.create"
723
+ ]
724
+ },
725
+ {
726
+ "required": [
727
+ "sharepoint.item.update"
728
+ ]
729
+ },
730
+ {
731
+ "required": [
732
+ "sharepoint.drive.list"
733
+ ]
734
+ },
735
+ {
736
+ "required": [
737
+ "sharepoint.file.list"
738
+ ]
739
+ },
740
+ {
741
+ "required": [
742
+ "sharepoint.file.search"
743
+ ]
744
+ },
745
+ {
746
+ "required": [
747
+ "sharepoint.file.read"
748
+ ]
749
+ },
750
+ {
751
+ "required": [
752
+ "sharepoint.file.upload"
753
+ ]
754
+ },
624
755
  {
625
756
  "required": [
626
757
  "warehouse.view.read"
@@ -818,6 +949,65 @@
818
949
  }
819
950
  }
820
951
  },
952
+ "company-sharepoint": {
953
+ "kind": "saas",
954
+ "operations": {
955
+ "sharepoint.list.list": {
956
+ "identity": "user",
957
+ "resources": [
958
+ "intranet"
959
+ ]
960
+ },
961
+ "sharepoint.item.list": {
962
+ "identity": "user",
963
+ "resources": [
964
+ "intranet"
965
+ ]
966
+ },
967
+ "sharepoint.item.create": {
968
+ "identity": "user",
969
+ "resources": [
970
+ "intranet"
971
+ ]
972
+ },
973
+ "sharepoint.item.update": {
974
+ "identity": "user",
975
+ "resources": [
976
+ "intranet"
977
+ ]
978
+ },
979
+ "sharepoint.drive.list": {
980
+ "identity": "user",
981
+ "resources": [
982
+ "intranet"
983
+ ]
984
+ },
985
+ "sharepoint.file.list": {
986
+ "identity": "user",
987
+ "resources": [
988
+ "intranet"
989
+ ]
990
+ },
991
+ "sharepoint.file.search": {
992
+ "identity": "user",
993
+ "resources": [
994
+ "intranet"
995
+ ]
996
+ },
997
+ "sharepoint.file.read": {
998
+ "identity": "user",
999
+ "resources": [
1000
+ "intranet"
1001
+ ]
1002
+ },
1003
+ "sharepoint.file.upload": {
1004
+ "identity": "user",
1005
+ "resources": [
1006
+ "intranet"
1007
+ ]
1008
+ }
1009
+ }
1010
+ },
821
1011
  "sales-warehouse": {
822
1012
  "kind": "database",
823
1013
  "operations": {
@@ -0,0 +1,51 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://schemas.harbour.dev/app-sign-in.schema.json",
4
+ "title": "AppSignIn",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "properties": {
8
+ "signIn": {
9
+ "type": "string",
10
+ "enum": [
11
+ "company",
12
+ "external"
13
+ ]
14
+ },
15
+ "signInMethods": {
16
+ "type": "array",
17
+ "items": {
18
+ "type": "string",
19
+ "enum": [
20
+ "phone",
21
+ "email"
22
+ ]
23
+ },
24
+ "minItems": 1,
25
+ "maxItems": 1
26
+ },
27
+ "clientId": {
28
+ "type": "string"
29
+ }
30
+ },
31
+ "required": [],
32
+ "allOf": [
33
+ {
34
+ "if": {
35
+ "properties": {
36
+ "signIn": {
37
+ "const": "external"
38
+ }
39
+ },
40
+ "required": [
41
+ "signIn"
42
+ ]
43
+ },
44
+ "then": {
45
+ "required": [
46
+ "signInMethods"
47
+ ]
48
+ }
49
+ }
50
+ ]
51
+ }
@@ -2,7 +2,7 @@
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
3
  "$id": "https://schemas.harbour.dev/data-grant-v2.schema.json",
4
4
  "title": "DataGrantV2",
5
- "description": "An app's integration grant for one connection, environment and identity mode (control table sk APP#<appId>#IGRANT#<environment>#<sourceId>#<mode>; grantId = base64url(JSON [\"v2\",appId,environment,sourceId,mode])). Additive to the legacy DataGrant (data-grant.schema.json), which is never consulted by v2 paths. A fresh REQUESTED record carries empty `operations`/`resources` until the attached request is approved; approved resources are structured `{name, columns?}` entries (a Slack channel alias, the fixed Gmail `inbox` alias, a Basecamp project alias or the fixed Basecamp `account` alias, or a warehouse view alias with its approved columns). Expiry is enforced from UTC time on every call and SDK calls never extend it; `expiredAt` is stamped by the recovery sweep afterwards. Status edges live in x-transitions; DENIED and REVOKED are terminal (a regrant after revocation is a new REQUESTED record once cleanup is DONE). Database grants add credentialRef/mintedPrincipal; both hold references only. An app-mode Slack grant may carry `presentation` (0.53.0): the IT-approved display name and icon the app's posts go out under, copied from the approved request and read by every post — never from the call. `identityMode` and `installation` are the deprecated 0.45.0 spellings: the record carries `mode`, and a SaaS grant runs on the connection's single installation.",
5
+ "description": "An app's integration grant for one connection, environment and identity mode (control table sk APP#<appId>#IGRANT#<environment>#<sourceId>#<mode>; grantId = base64url(JSON [\"v2\",appId,environment,sourceId,mode])). Additive to the legacy DataGrant (data-grant.schema.json), which is never consulted by v2 paths. A fresh REQUESTED record carries empty `operations`/`resources` until the attached request is approved; approved resources are structured `{name, columns?}` entries (a Slack channel alias, the fixed Gmail `inbox` alias, a Basecamp project alias or the fixed Basecamp `account` alias, a SharePoint site alias, or a warehouse view alias with its approved columns). Expiry is enforced from UTC time on every call and SDK calls never extend it; `expiredAt` is stamped by the recovery sweep afterwards. Status edges live in x-transitions; DENIED and REVOKED are terminal (a regrant after revocation is a new REQUESTED record once cleanup is DONE). Database grants add credentialRef/mintedPrincipal; both hold references only. An app-mode Slack grant may carry `presentation` (0.53.0): the IT-approved display name and icon the app's posts go out under, copied from the approved request and read by every post — never from the call. `identityMode` and `installation` are the deprecated 0.45.0 spellings: the record carries `mode`, and a SaaS grant runs on the connection's single installation.",
6
6
  "type": "object",
7
7
  "additionalProperties": false,
8
8
  "required": ["schema", "tenantId", "appId", "environment", "sourceId", "mode", "kind", "status", "operations", "resources", "version", "provisioning", "createdAt", "updatedAt"],
@@ -17,10 +17,10 @@
17
17
  "status": { "$ref": "#/definitions/DataGrantV2Status" },
18
18
  "operations": {
19
19
  "type": "array",
20
- "maxItems": 22,
20
+ "maxItems": 31,
21
21
  "uniqueItems": true,
22
22
  "items": { "$ref": "app-integrations-declaration.schema.json#/definitions/IntegrationOperation" },
23
- "description": "Approved operations; each must match this grant's mode. Empty until the first approval. At most the twenty-two SaaS operations (0.76.0: eleven Slack and Gmail, eleven Basecamp); a database grant holds one."
23
+ "description": "Approved operations; each must match this grant's mode. Empty until the first approval. At most the thirty-one SaaS operations (0.78.0: eleven Slack and Gmail, eleven Basecamp, nine SharePoint); a database grant holds one."
24
24
  },
25
25
  "resources": {
26
26
  "type": "array",
@@ -62,7 +62,7 @@
62
62
  "type": "object",
63
63
  "additionalProperties": false,
64
64
  "required": ["name"],
65
- "description": "One approved logical resource: a Slack channel alias, the fixed Gmail `inbox` alias, a Basecamp project alias or the fixed Basecamp `account` alias (0.76.0), or a warehouse view alias with the approved columns.",
65
+ "description": "One approved logical resource: a Slack channel alias, the fixed Gmail `inbox` alias, a Basecamp project alias or the fixed Basecamp `account` alias (0.76.0), a SharePoint site alias (0.78.0), or a warehouse view alias with the approved columns.",
66
66
  "properties": {
67
67
  "name": { "$ref": "app-integrations-declaration.schema.json#/definitions/IntegrationAlias" },
68
68
  "columns": {
@@ -19,6 +19,9 @@
19
19
  "allowedUsers": {"type": "array", "items": {"type": "string"}},
20
20
  "allowedGroups": {"type": "array", "items": {"type": "string"}},
21
21
  "enabled": {"type": "boolean"},
22
- "workloadPrincipalArn": {"type": "string", "pattern": "^arn:aws:(iam|sts)::[0-9]+:"}
23
- }
22
+ "workloadPrincipalArn": {"type": "string", "pattern": "^arn:aws:(iam|sts)::[0-9]+:"},
23
+ "signIn": {"type": "string", "enum": ["company", "external"]},
24
+ "signInMethods": {"type": "array", "items": {"type": "string", "enum": ["phone", "email"]}, "minItems": 1, "maxItems": 1}
25
+ },
26
+ "allOf": [{"if": {"properties": {"signIn": {"const": "external"}}, "required": ["signIn"]}, "then": {"required": ["signInMethods"]}}]
24
27
  }
@@ -0,0 +1,120 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://schemas.harbour.dev/external-sign-in.schema.json",
4
+ "title": "ExternalSignIn",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "properties": {
8
+ "enabledMethods": {
9
+ "type": "array",
10
+ "items": {
11
+ "type": "string",
12
+ "enum": [
13
+ "phone",
14
+ "email"
15
+ ]
16
+ },
17
+ "uniqueItems": true
18
+ },
19
+ "email": {
20
+ "type": "object",
21
+ "additionalProperties": false,
22
+ "properties": {
23
+ "senderEmail": {
24
+ "type": "string"
25
+ },
26
+ "senderDomain": {
27
+ "type": "string"
28
+ },
29
+ "sesRegion": {
30
+ "type": "string"
31
+ },
32
+ "configurationSet": {
33
+ "type": "string"
34
+ }
35
+ },
36
+ "required": [
37
+ "senderEmail",
38
+ "sesRegion"
39
+ ]
40
+ },
41
+ "sms": {
42
+ "type": "object",
43
+ "additionalProperties": false,
44
+ "properties": {
45
+ "originationIdentity": {
46
+ "type": "string"
47
+ },
48
+ "region": {
49
+ "type": "string"
50
+ },
51
+ "inEntityId": {
52
+ "type": "string"
53
+ },
54
+ "inTemplateId": {
55
+ "type": "string"
56
+ }
57
+ },
58
+ "required": [
59
+ "region"
60
+ ]
61
+ },
62
+ "directory": {
63
+ "type": "object",
64
+ "additionalProperties": false,
65
+ "properties": {
66
+ "accountId": {
67
+ "type": "string"
68
+ },
69
+ "region": {
70
+ "type": "string"
71
+ },
72
+ "userPoolId": {
73
+ "type": "string"
74
+ }
75
+ },
76
+ "required": [
77
+ "accountId",
78
+ "region",
79
+ "userPoolId"
80
+ ]
81
+ },
82
+ "readiness": {
83
+ "type": "object",
84
+ "additionalProperties": false,
85
+ "properties": {
86
+ "email": {
87
+ "type": "object",
88
+ "properties": {
89
+ "senderVerified": {
90
+ "type": "boolean"
91
+ },
92
+ "productionAccess": {
93
+ "type": "boolean"
94
+ }
95
+ },
96
+ "required": [
97
+ "senderVerified",
98
+ "productionAccess"
99
+ ],
100
+ "additionalProperties": false
101
+ },
102
+ "sms": {
103
+ "type": "object",
104
+ "properties": {
105
+ "sandbox": {
106
+ "type": "boolean"
107
+ }
108
+ },
109
+ "required": [
110
+ "sandbox"
111
+ ],
112
+ "additionalProperties": false
113
+ }
114
+ }
115
+ }
116
+ },
117
+ "required": [
118
+ "enabledMethods"
119
+ ]
120
+ }