@lanes-sh/link 0.6.11 → 0.7.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.
- package/README.md +62 -45
- package/instructions/skills/lanes-link/SKILL.md +25 -0
- package/package.json +3 -2
- package/src/audit/conformance.ts +1 -1
- package/src/cli/argv.ts +14 -1
- package/src/cli/commands/connect/acquire.ts +100 -0
- package/src/cli/commands/connect/custom/index.ts +1 -1
- package/src/cli/commands/connect/declare.ts +19 -0
- package/src/cli/commands/connect/index.ts +54 -56
- package/src/cli/commands/connect/requirements.ts +23 -1
- package/src/cli/commands/connect/setup.ts +1 -1
- package/src/cli/commands/connect/variables.ts +220 -0
- package/src/cli/commands/knowledge/index.ts +22 -4
- package/src/cli/commands/knowledge/migrate.ts +61 -43
- package/src/cli/commands/operate/tools.ts +1 -1
- package/src/cli/commands/owner/entities.ts +244 -0
- package/src/cli/commands/owner/shared.ts +14 -0
- package/src/cli/commands/owner/vault.ts +2 -2
- package/src/cli/commands/owner.ts +13 -3
- package/src/cli/commands/setup.ts +12 -0
- package/src/cli/config-edit.ts +16 -6
- package/src/cli/config-repair.ts +10 -0
- package/src/cli/dispatch-owner.ts +30 -1
- package/src/cli/main.ts +2 -1
- package/src/cli/runtime/open.ts +14 -7
- package/src/cli/runtime/registry.ts +6 -1
- package/src/cli/selection.ts +11 -0
- package/src/cli/usage.ts +13 -2
- package/src/connectivity/auth/strategy/index.ts +1 -1
- package/src/connectivity/capability.ts +1 -1
- package/src/connectivity/context.ts +1 -1
- package/src/connectivity/index.ts +1 -1
- package/src/connectivity/mail/attachments.ts +42 -73
- package/src/connectivity/mail/content-type.ts +71 -0
- package/src/connectivity/mail/index.ts +1 -1
- package/src/connectivity/manifest/provider.ts +50 -0
- package/src/connectivity/manifest/variables.ts +173 -0
- package/src/connectivity/transports/factory.ts +74 -1
- package/src/connectivity/transports/http/index.ts +8 -2
- package/src/connectivity/transports/http/keys.ts +83 -0
- package/src/connectivity/transports/imap/attachment.ts +53 -10
- package/src/connectivity/transports/imap/capabilities.ts +28 -0
- package/src/connectivity/transports/imap/download.ts +111 -0
- package/src/connectivity/transports/imap/index.ts +13 -0
- package/src/connectivity/transports/imap/operations.ts +1 -0
- package/src/deployments/adapters/s3.ts +1 -1
- package/src/deployments/gcp/provision.ts +1 -1
- package/src/deployments/knowledge.ts +44 -18
- package/src/deployments/prepare.ts +1 -1
- package/src/deployments/serving.ts +1 -1
- package/src/dispatch/dispatch.ts +17 -10
- package/src/dispatch/staging.ts +76 -1
- package/src/profile/knowledge.ts +19 -11
- package/src/profile/schema.ts +2 -2
- package/src/providers/README.md +189 -0
- package/src/providers/airtable/index.ts +10 -0
- package/src/providers/algolia/index.ts +10 -0
- package/src/providers/amplitude/index.ts +10 -0
- package/src/providers/apify/index.ts +10 -0
- package/src/providers/asana/index.ts +10 -0
- package/src/providers/assets/provider.ts +11 -4
- package/src/providers/atlassian/index.ts +19 -0
- package/src/providers/attio/index.ts +10 -0
- package/src/providers/betterstack/index.ts +10 -0
- package/src/providers/box/index.ts +64 -0
- package/src/providers/brightdata/index.ts +10 -0
- package/src/providers/buildkite/index.ts +10 -0
- package/src/providers/bunq/index.ts +2 -2
- package/src/providers/calendly/index.ts +10 -0
- package/src/providers/canva/index.ts +10 -0
- package/src/providers/circleci/index.ts +10 -0
- package/src/providers/clickup/index.ts +10 -0
- package/src/providers/close/index.ts +10 -0
- package/src/providers/cloudflare_bindings/index.ts +14 -0
- package/src/providers/cloudflare_observability/index.ts +10 -0
- package/src/providers/contentful/index.ts +10 -0
- package/src/providers/custom/load.ts +1 -1
- package/src/providers/datadog/index.ts +10 -0
- package/src/providers/discord/index.ts +1 -1
- package/src/providers/discord/specs/discord.v10.json +0 -88
- package/src/providers/discord/specs/vendor.ts +1 -1
- package/src/providers/dropbox/index.ts +10 -0
- package/src/providers/entities/catalogue.ts +366 -0
- package/src/providers/entities/find.ts +279 -0
- package/src/providers/entities/provider.ts +334 -0
- package/src/providers/entities/render.ts +142 -0
- package/src/providers/entities/store.ts +276 -0
- package/src/providers/entities/writes.ts +279 -0
- package/src/providers/example/provider.ts +1 -1
- package/src/providers/expensify/index.ts +10 -0
- package/src/providers/fastmail/calendar/index.ts +21 -0
- package/src/providers/fastmail/contacts/index.ts +17 -0
- package/src/providers/fastmail/index.ts +4 -0
- package/src/providers/fastmail/mail/index.ts +38 -0
- package/src/providers/fastmail/shared/setup.ts +52 -0
- package/src/providers/figma/index.ts +10 -0
- package/src/providers/fireflies/index.ts +10 -0
- package/src/providers/flagsmith/index.ts +10 -0
- package/src/providers/gamma/index.ts +10 -0
- package/src/providers/github/index.ts +2 -2
- package/src/providers/google/gmail/attachment.ts +16 -1
- package/src/providers/google/gmail-imap/index.ts +7 -2
- package/src/providers/google/shared/oauth.ts +1 -1
- package/src/providers/google/shared/service-account.ts +1 -1
- package/src/providers/google/shared/setup.ts +1 -1
- package/src/providers/google/specs/calendar.v3.json +0 -32
- package/src/providers/google/specs/docs.v1.json +0 -76
- package/src/providers/google/specs/drive.v3.json +0 -32
- package/src/providers/google/specs/gmail.v1.json +0 -76
- package/src/providers/google/specs/people.v1.json +0 -77
- package/src/providers/google/specs/sheets.v4.json +0 -76
- package/src/providers/google/specs/tasks.v1.json +0 -76
- package/src/providers/grafana/index.ts +10 -0
- package/src/providers/heroku/index.ts +10 -0
- package/src/providers/hubspot/index.ts +75 -0
- package/src/providers/hygraph/index.ts +10 -0
- package/src/providers/icloud/mail/index.ts +5 -0
- package/src/providers/icloud/shared/setup.ts +1 -1
- package/src/providers/index.ts +255 -0
- package/src/providers/insightly/index.ts +10 -0
- package/src/providers/jam/index.ts +10 -0
- package/src/providers/klaviyo/index.ts +10 -0
- package/src/providers/mailbox/index.ts +87 -0
- package/src/providers/memory/provider.ts +3 -8
- package/src/providers/mercury/index.ts +10 -0
- package/src/providers/microsoft/calendar/index.ts +49 -0
- package/src/providers/microsoft/contacts/index.ts +50 -0
- package/src/providers/microsoft/drive/index.ts +62 -0
- package/src/providers/microsoft/index.ts +12 -0
- package/src/providers/microsoft/mail/index.ts +76 -0
- package/src/providers/microsoft/shared/oauth.ts +58 -0
- package/src/providers/microsoft/shared/scopes.ts +56 -0
- package/src/providers/microsoft/shared/setup.ts +45 -0
- package/src/providers/microsoft/specs/microsoft-todo.v1.json +755 -0
- package/src/providers/microsoft/specs/onedrive.v1.json +993 -0
- package/src/providers/microsoft/specs/outlook-calendar.v1.json +1743 -0
- package/src/providers/microsoft/specs/outlook-contacts.v1.json +430 -0
- package/src/providers/microsoft/specs/outlook-mail.v1.json +901 -0
- package/src/providers/microsoft/specs/vendor.ts +232 -0
- package/src/providers/microsoft/todo/index.ts +54 -0
- package/src/providers/miro/index.ts +10 -0
- package/src/providers/mixpanel/index.ts +10 -0
- package/src/providers/monday/index.ts +10 -0
- package/src/providers/mux/index.ts +10 -0
- package/src/providers/navan/index.ts +10 -0
- package/src/providers/neon/index.ts +10 -0
- package/src/providers/netlify/index.ts +10 -0
- package/src/providers/nextcloud/calendar/index.ts +28 -0
- package/src/providers/nextcloud/contacts/index.ts +18 -0
- package/src/providers/nextcloud/index.ts +3 -0
- package/src/providers/nextcloud/shared/setup.ts +59 -0
- package/src/providers/owner.ts +15 -3
- package/src/providers/paddle/index.ts +10 -0
- package/src/providers/paypal/index.ts +10 -0
- package/src/providers/posthog/index.ts +10 -0
- package/src/providers/prisma/index.ts +10 -0
- package/src/providers/ramp/index.ts +10 -0
- package/src/providers/recurly/index.ts +10 -0
- package/src/providers/reddit/index.ts +1 -1
- package/src/providers/remote/index.ts +10 -0
- package/src/providers/render/index.ts +35 -0
- package/src/providers/replicate/index.ts +10 -0
- package/src/providers/resend/index.ts +10 -0
- package/src/providers/riverside/index.ts +10 -0
- package/src/providers/rootly/index.ts +10 -0
- package/src/providers/rudderstack/index.ts +10 -0
- package/src/providers/salesloft/index.ts +10 -0
- package/src/providers/sanity/index.ts +10 -0
- package/src/providers/scopes.ts +2 -0
- package/src/providers/sentry/index.ts +10 -0
- package/src/providers/setup/plan.ts +11 -0
- package/src/providers/setup/provider.ts +12 -0
- package/src/providers/shared/openapi.ts +70 -0
- package/src/providers/shared/slug.ts +28 -0
- package/src/providers/shared/vendor-operations.ts +43 -1
- package/src/providers/shared/vendor-spec.ts +98 -17
- package/src/providers/shortcut/index.ts +10 -0
- package/src/providers/slack/index.ts +2 -2
- package/src/providers/square/index.ts +10 -0
- package/src/providers/storyblok/index.ts +10 -0
- package/src/providers/stripe/index.ts +10 -0
- package/src/providers/supabase/index.ts +10 -0
- package/src/providers/tasks/store.ts +2 -7
- package/src/providers/tavily/index.ts +10 -0
- package/src/providers/todoist/index.ts +10 -0
- package/src/providers/untested.ts +105 -0
- package/src/providers/vault/provider.ts +1 -1
- package/src/providers/vercel/index.ts +10 -0
- package/src/providers/vimeo/index.ts +10 -0
- package/src/providers/webflow/index.ts +10 -0
- package/src/providers/whimsical/index.ts +10 -0
- package/src/providers/wix/index.ts +10 -0
- package/src/providers/workable/index.ts +10 -0
- package/src/providers/yahoo_mail/index.ts +73 -0
- package/src/providers/zapier/index.ts +10 -0
- package/src/providers/zoho_mail/index.ts +79 -0
- package/src/secrets/document.ts +1 -1
- package/src/server/attachments.ts +129 -5
- package/src/server/index.ts +3 -3
- package/src/server/mcp/instructions.ts +88 -18
- package/src/server/stdio.ts +1 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { defineProvider } from '#connectivity';
|
|
2
|
+
import {
|
|
3
|
+
CALENDAR_SCOPES,
|
|
4
|
+
CONTACTS_SCOPES,
|
|
5
|
+
FILES_SCOPES,
|
|
6
|
+
GRAPH_BASE_URL,
|
|
7
|
+
MAIL_SCOPES,
|
|
8
|
+
MICROSOFT_APP,
|
|
9
|
+
MICROSOFT_AUTHORIZE_URL,
|
|
10
|
+
MICROSOFT_IDENTITY,
|
|
11
|
+
MICROSOFT_TOKEN_URL,
|
|
12
|
+
TODO_SCOPES,
|
|
13
|
+
specPath,
|
|
14
|
+
} from '../shared/oauth.ts';
|
|
15
|
+
import { microsoftSetup } from '../shared/setup.ts';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Outlook mail, through Microsoft Graph.
|
|
19
|
+
*
|
|
20
|
+
* The REST half of the Microsoft family, and the reason there is no IMAP one
|
|
21
|
+
* beside it: Microsoft retired basic authentication for Outlook.com IMAP, so an
|
|
22
|
+
* app password is not a route here the way it is for iCloud, Fastmail, or a
|
|
23
|
+
* personal Gmail. Graph with a browser sign-in is what works.
|
|
24
|
+
*
|
|
25
|
+
* `send_message` is a vendored operation rather than authored code, unlike
|
|
26
|
+
* Gmail's — Graph composes the message from JSON, so nothing here has to
|
|
27
|
+
* assemble RFC 2822. What it does not do is attachments: Graph carries those as
|
|
28
|
+
* base64 inside the message, which is the thing ADR-017 exists to avoid, so the
|
|
29
|
+
* field is deliberately absent from the vendored body rather than offered and
|
|
30
|
+
* expensive.
|
|
31
|
+
*/
|
|
32
|
+
export const outlookMail = defineProvider({
|
|
33
|
+
id: 'outlook_mail',
|
|
34
|
+
name: 'Outlook Mail',
|
|
35
|
+
description:
|
|
36
|
+
'Read, search, file, and send mail in an Outlook or Microsoft 365 mailbox, via Microsoft Graph.',
|
|
37
|
+
connector: {
|
|
38
|
+
kind: 'http',
|
|
39
|
+
// Graph carries its version in the path of the server URL, like Drive and
|
|
40
|
+
// unlike Sheets. `cli/tools.test.ts` checks this equals the spec's own
|
|
41
|
+
// `servers[0].url`.
|
|
42
|
+
base_url: GRAPH_BASE_URL,
|
|
43
|
+
openapi: specPath('outlook-mail.v1.json'),
|
|
44
|
+
},
|
|
45
|
+
auth: {
|
|
46
|
+
kind: 'oauth',
|
|
47
|
+
registration: 'manual',
|
|
48
|
+
app: MICROSOFT_APP,
|
|
49
|
+
// Declared rather than discovered. An `http` connector has no metadata
|
|
50
|
+
// document to read — a REST API does not announce where its authorization
|
|
51
|
+
// server lives — so the two endpoints are part of the manifest.
|
|
52
|
+
authorize_url: MICROSOFT_AUTHORIZE_URL,
|
|
53
|
+
token_url: MICROSOFT_TOKEN_URL,
|
|
54
|
+
scopes: MAIL_SCOPES,
|
|
55
|
+
revoke_url: 'https://account.live.com/consent/Manage',
|
|
56
|
+
},
|
|
57
|
+
identity: MICROSOFT_IDENTITY,
|
|
58
|
+
setup: microsoftSetup('Outlook Mail', MAIL_SCOPES),
|
|
59
|
+
// Keyed on the capability name as it is *served* — dots, not underscores.
|
|
60
|
+
// Graph's operationIds are `me.ListMessages` and nothing strips the `me.`,
|
|
61
|
+
// because `shortenName` removes the provider id and the provider is not
|
|
62
|
+
// called "me". A key that misses does not error: it withholds every argument
|
|
63
|
+
// and reads exactly like working redaction.
|
|
64
|
+
redact: {
|
|
65
|
+
// Never `search` or `filter`: a query is content, and "who did I email
|
|
66
|
+
// about the diagnosis" is the whole message.
|
|
67
|
+
'me.ListMessages': ['top', 'orderby', 'select'],
|
|
68
|
+
'me.GetMessages': ['message-id', 'select'],
|
|
69
|
+
'me.UpdateMessages': ['message-id', 'isRead', 'categories', 'flag', 'importance'],
|
|
70
|
+
'me.ListMailFolders': ['top', 'orderby', 'select'],
|
|
71
|
+
'me.messages.ListAttachments': ['message-id', 'top', 'orderby', 'select'],
|
|
72
|
+
'me.messages.GetAttachments': ['message-id', 'attachment-id', 'select'],
|
|
73
|
+
// Nothing. The recipients, the subject, and the body are the message.
|
|
74
|
+
'me.sendMail': ['saveToSentItems'],
|
|
75
|
+
},
|
|
76
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** The `oauth_apps` entry every Microsoft provider authorises against. */
|
|
2
|
+
export const MICROSOFT_APP = 'microsoft';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* One app registration, five providers.
|
|
6
|
+
*
|
|
7
|
+
* Microsoft Graph is a single API behind mail, calendars, contacts, files and
|
|
8
|
+
* to-do, so unlike Google — where each product has its own client and its own
|
|
9
|
+
* consent screen — there is one Entra registration here and the providers differ
|
|
10
|
+
* only in what they ask it for. The token still lands per provider, exactly as
|
|
11
|
+
* Gmail's and Drive's do: `app` moves where the *client* comes from, never where
|
|
12
|
+
* the tokens go, so connecting Outlook mail does not silently grant OneDrive.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** `common` rather than a tenant id: personal accounts and work accounts both. */
|
|
16
|
+
export const MICROSOFT_AUTHORIZE_URL =
|
|
17
|
+
'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
|
|
18
|
+
export const MICROSOFT_TOKEN_URL = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Asked for by every provider, and neither reaches a service.
|
|
22
|
+
*
|
|
23
|
+
* `offline_access` is not optional and is the one to get wrong: Microsoft issues
|
|
24
|
+
* no refresh token without it, so the connection authorises cleanly, works for
|
|
25
|
+
* about an hour, and then stops. That is the same failure Google's
|
|
26
|
+
* `access_type=offline` exists to prevent, and it is worth naming because the
|
|
27
|
+
* successful-looking response is what makes it hard to debug an hour later.
|
|
28
|
+
*
|
|
29
|
+
* `User.Read` is what the identity probe reads — the account's own name and
|
|
30
|
+
* address, so a connection can be labelled with whose it is. It reaches no
|
|
31
|
+
* mailbox, no calendar, and no file.
|
|
32
|
+
*/
|
|
33
|
+
export const MICROSOFT_BASE_SCOPES = ['offline_access', 'User.Read'] as const;
|
|
34
|
+
|
|
35
|
+
export const MAIL_SCOPES = [...MICROSOFT_BASE_SCOPES, 'Mail.ReadWrite', 'Mail.Send'];
|
|
36
|
+
export const CALENDAR_SCOPES = [...MICROSOFT_BASE_SCOPES, 'Calendars.ReadWrite'];
|
|
37
|
+
export const CONTACTS_SCOPES = [...MICROSOFT_BASE_SCOPES, 'Contacts.Read'];
|
|
38
|
+
export const FILES_SCOPES = [...MICROSOFT_BASE_SCOPES, 'Files.ReadWrite'];
|
|
39
|
+
export const TODO_SCOPES = [...MICROSOFT_BASE_SCOPES, 'Tasks.ReadWrite'];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Whose account this is, for the label a connection is listed under.
|
|
43
|
+
*
|
|
44
|
+
* `userPrincipalName` rather than `mail`: a personal Microsoft account often has
|
|
45
|
+
* no `mail` at all, and a null there would send `connect` to its "which account
|
|
46
|
+
* is this?" fallback on exactly the accounts this is most useful for.
|
|
47
|
+
*/
|
|
48
|
+
export const MICROSOFT_IDENTITY = {
|
|
49
|
+
kind: 'http' as const,
|
|
50
|
+
url: 'https://graph.microsoft.com/v1.0/me',
|
|
51
|
+
field: 'userPrincipalName',
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
/** Graph is one host and one version, for all five. */
|
|
55
|
+
export const GRAPH_BASE_URL = 'https://graph.microsoft.com/v1.0';
|
|
56
|
+
|
|
57
|
+
export const specPath = (file: string): string =>
|
|
58
|
+
new URL(`../specs/${file}`, import.meta.url).pathname;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { ScopeMeaning } from '../../scopes.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* What the Microsoft Graph scopes we ship actually permit, in plain words.
|
|
5
|
+
*
|
|
6
|
+
* Vendor knowledge, so it lives with the vendor — the same reasoning as
|
|
7
|
+
* `../../google/shared/scopes.ts`, and the same confinement: nothing routes on
|
|
8
|
+
* this, and a scope missing from the table is printed unannotated rather than
|
|
9
|
+
* mis-described.
|
|
10
|
+
*/
|
|
11
|
+
export const MICROSOFT_SCOPE_MEANINGS: Record<string, ScopeMeaning> = {
|
|
12
|
+
offline_access: {
|
|
13
|
+
meaning:
|
|
14
|
+
'keep the connection working without sending you to a browser again — Microsoft issues no refresh token without it',
|
|
15
|
+
},
|
|
16
|
+
'User.Read': {
|
|
17
|
+
meaning: 'your name and address, so this connection can be labelled with whose it is. No mail, calendar, or files',
|
|
18
|
+
},
|
|
19
|
+
// Graph's mail scopes are coarser than Gmail's. There is no equivalent of
|
|
20
|
+
// `gmail.metadata` or a per-message grant, so reading one message means the
|
|
21
|
+
// grant reaches every message — which is exactly why `gmail.modify` is on this
|
|
22
|
+
// list too.
|
|
23
|
+
'Mail.ReadWrite': {
|
|
24
|
+
meaning: 'read, file, and modify any message in the mailbox; no permanent delete',
|
|
25
|
+
broad: true,
|
|
26
|
+
},
|
|
27
|
+
'Mail.Read': { meaning: 'read any message in the mailbox' },
|
|
28
|
+
// Broad for where it lands rather than what it reaches. A sent message leaves
|
|
29
|
+
// the account, arrives as the person, and cannot be recalled — the same
|
|
30
|
+
// argument that puts Reddit's three on the broad list.
|
|
31
|
+
'Mail.Send': {
|
|
32
|
+
meaning: 'send mail as you — it leaves the account under your name and cannot be recalled',
|
|
33
|
+
broad: true,
|
|
34
|
+
},
|
|
35
|
+
'Calendars.ReadWrite': {
|
|
36
|
+
meaning: 'read and write every event in every calendar on the account, including invitations sent to others',
|
|
37
|
+
broad: true,
|
|
38
|
+
},
|
|
39
|
+
'Calendars.Read': { meaning: 'read every event in every calendar on the account' },
|
|
40
|
+
'Contacts.Read': { meaning: 'read the address book. Read-only — nothing here writes a contact' },
|
|
41
|
+
// Broad, and the only one here that is broad for want of a narrower option.
|
|
42
|
+
// Google Drive is reached with `drive.file`, which covers files this app made
|
|
43
|
+
// or the person picked and nothing else; Graph publishes no equivalent, so the
|
|
44
|
+
// smallest grant that can create a folder is one that reaches every file in
|
|
45
|
+
// the drive.
|
|
46
|
+
'Files.ReadWrite': {
|
|
47
|
+
meaning: 'read and write every file in your OneDrive — Microsoft publishes no per-file equivalent of Google\'s drive.file',
|
|
48
|
+
broad: true,
|
|
49
|
+
},
|
|
50
|
+
'Files.Read': { meaning: 'read every file in your OneDrive' },
|
|
51
|
+
'Tasks.ReadWrite': {
|
|
52
|
+
meaning: 'read and write every list and task in Microsoft To Do',
|
|
53
|
+
broad: true,
|
|
54
|
+
},
|
|
55
|
+
'Tasks.Read': { meaning: 'read every list and task in Microsoft To Do' },
|
|
56
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { MICROSOFT_APP } from './oauth.ts';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The console walkthrough, shared by all five providers.
|
|
5
|
+
*
|
|
6
|
+
* Parameterised by product name and by the permissions that product asks for,
|
|
7
|
+
* because the registration is one app and the consent is per provider — someone
|
|
8
|
+
* connecting only To Do should not be told to tick mail permissions.
|
|
9
|
+
*
|
|
10
|
+
* A registration of the operator's own, with no broker behind it. Microsoft does
|
|
11
|
+
* not offer dynamic client registration, so a client has to exist before the
|
|
12
|
+
* browser opens; until Lanes operates one, that client is theirs. `--own-client`
|
|
13
|
+
* is not a flag here, it is the only route — which is the `reddit` shape, and
|
|
14
|
+
* the reason `setup.prompts` carries `scope: shared` entries rather than a
|
|
15
|
+
* pasted token.
|
|
16
|
+
*/
|
|
17
|
+
export const microsoftSetup = (product: string, permissions: readonly string[]) => ({
|
|
18
|
+
summary:
|
|
19
|
+
`${product} authorises in a browser against an app registration of your own in Microsoft Entra. ` +
|
|
20
|
+
`Registering one is free and takes a few minutes; it is a public client, so there is no secret ` +
|
|
21
|
+
`to keep. The same registration covers Outlook mail, calendar, contacts, OneDrive and To Do — ` +
|
|
22
|
+
`you do this once, not once per provider.`,
|
|
23
|
+
docs: 'https://lanes.sh/docs/link/connect',
|
|
24
|
+
docs_url: 'https://entra.microsoft.com',
|
|
25
|
+
steps: [
|
|
26
|
+
'Open https://entra.microsoft.com and go to Applications → App registrations → New registration.',
|
|
27
|
+
'Name it "Lanes Link". Under "Supported account types", pick the option that includes personal Microsoft accounts if this is an @outlook.com or @hotmail.com address — the default is work accounts only, and choosing it is what makes a personal account fail at sign-in rather than at registration.',
|
|
28
|
+
'Under "Redirect URI", choose the platform "Mobile and desktop applications" and enter exactly: http://localhost — no port. Microsoft accepts any port on a loopback redirect for this platform, which is what lets connect listen on whichever one is free.',
|
|
29
|
+
'Register, then copy the "Application (client) ID" from the overview page. That is the value asked for below.',
|
|
30
|
+
'Leave "Certificates & secrets" alone. This is a public client: a secret shipped to a program someone runs is not a secret, so none is created and none is asked for.',
|
|
31
|
+
`Permissions are requested at sign-in rather than configured here, so there is nothing to add under "API permissions" first. ${product} asks for: ${permissions.join(', ')}.`,
|
|
32
|
+
],
|
|
33
|
+
troubleshooting:
|
|
34
|
+
'AADSTS50011 means the redirect URI does not match: the registration needs the platform "Mobile and desktop applications" with http://localhost, not the "Web" platform, which pins the whole URL including the port. ' +
|
|
35
|
+
'AADSTS50020 means the account type is wrong — a personal Microsoft account signing in to a registration made for work accounts only. Change it under Authentication → Supported account types and re-run: lanes link connect <provider> --replace.',
|
|
36
|
+
prompts: [
|
|
37
|
+
{
|
|
38
|
+
key: 'client_id',
|
|
39
|
+
label: 'Application (client) ID',
|
|
40
|
+
secret: false,
|
|
41
|
+
scope: 'shared' as const,
|
|
42
|
+
credential_ref: `${MICROSOFT_APP}/client_id`,
|
|
43
|
+
},
|
|
44
|
+
],
|
|
45
|
+
});
|