Docs
/

@leumas/connectors

Connectors — logged-in users link third-party accounts (databases, social/OAuth, SSH/SFTP). A per-provider connector registry + createConnectorsRouter (CRUD connections + test-connection). Absorbs...

@leumas/connectors

Logged-in users link third-party accounts — databases (Mongo, SQL, Redis, Firebase), media (Cloudinary), social/OAuth (Google, GitHub, Facebook, LinkedIn, YouTube, TikTok), and SSH/SFTP hosts. One connector registry powers the API, the connect form, and the Studio page.

Absorbs (DRY-consolidated from): leumas-middleware/database-connector (Mongo/SQL/Redis/Firebase/ Cloudinary adapters) + leumas-cursor-agent-mvp (databasesController, socialConnectionsController = OAuth, sshProfilesController = SSH/SFTP).

The model

A Connector describes one integration a user can link — its provider id, family (database | media | social | ssh), the form fields, which fields are secret, and a test(config) probe. Drivers (mongodb, redis, ssh2, …) are lazy-loaded inside test() so this engine has no hard driver dependency.

A Connection is a saved link: { id, owner, provider, name, config, lastTest }. Secrets are never returned to the client (masked as ••••••).

Usage (in leumas-api)

import { createConnectorsRouter } from '@leumas/connectors';
import { requireAuth } from '@leumas/auth';

// `store` persists the per-user `connections` collection (back it with @leumas/middleware).
app.use('/api/connectors', createConnectorsRouter({ store, requireAuth }));

The store contract

store.list({ owner })                → Connection[]
store.get(id, { owner })             → Connection | null
store.create(connection, { owner })  → Connection
store.update(id, changes, { owner }) → Connection
store.remove(id, { owner })          → void

createMemoryStore() is a zero-dep default for dev/tests.

Routes

MethodPathPurpose
GET/providersconnector manifests (fields, family, auth)
GET/this user's connections (secrets masked)
POST/create { provider, name, config }
GET/PUT/DELETE/:idread / update / remove a connection
POST/:id/testtest a saved connection
POST/testtest an unsaved { provider, config }
GET/:provider/authorizeOAuth authorize URL (social connectors)

Add a provider

import { defineConnector } from '@leumas/connectors';

export const stripe = defineConnector({
  provider: 'stripe', family: 'media', name: 'Stripe',
  fields: [{ name: 'secretKey', type: 'password', required: true }],
  async test(config) { /* probe */ return { ok: true }; },
});

Pass it in connectors: [...allConnectors, stripe] to createConnectorsRouter, or add it to src/providers/index.js.

Operations — what a connection can actually DO

A connector carries an .integration payload ({ baseUrl, auth, operations }) and that one property is what makes it callable: executeOperation, createIntegrationRunner, the /:id/operations route, the grid's integration: cell and @leumas/invoke's integration kind all look for it and nothing else.

  • api-family connectors get it from defineApiIntegration (src/providers/api/catalog.js).
  • OAuth connectors get it from src/providers/operations/<provider>.js — one pure-data file per

provider, assembled by operations/index.js and attached in providers/social.js. 156 operations across 27 providers.

  • A provider with no catalog is listed in UNCATALOGUED with the sentence saying why, which the

Studio panel shows instead of an empty list. The rule: a provider gets a catalog when a bearer token is enough to call it; when it is not, it gets a sentence.

Declare parameters with the compact spec in operations/_shared.js:

params: args({
  '*id': 'string|Required — the star means required.',
  part:  'string=snippet|A default, applied before the call.',
  mine:  'boolean=true|Typed: this is a real boolean, not "true".',
})

An operation may also declare scopes: [...] (needs more than the read-ish defaults), bodyStyle: 'json' | 'form' | 'multipart', and uploadStyle: 'google-resumable'.

[warning] A declared scope must be in the provider descriptor's scopes or optionalScopes. If it is in neither, the authorize URL never asks for it — so it can never be granted and the operation can never work, on any account, with no error anywhere. pnpm smoke:connector-ops asserts this.

Environment

VariableWhat it does
LEUMAS_SECRET_KEYSeals every credential at rest (aes-256-gcm, lsx1: prefix). Without it tokens and database passwords are stored in clear text, and the Connections page says so on the page rather than leaving you to infer it.
LEUMAS_OAUTH_<PROVIDER>_CLIENT_ID / _SECRETThis deployment's registered OAuth app. <PROVIDER> is the provider id uppercased with dashes as underscores — google-sheetsLEUMAS_OAUTH_GOOGLE_SHEETS_CLIENT_ID. The Google family falls back to the plain GOOGLE pair, so one registered Google app serves Docs, Drive, Sheets, Gmail, Calendar and YouTube.
LEUMAS_OAUTH_SHARED_APPS1 makes those env apps shared defaults a tenant may override with their own, instead of pinned (the default, where env wins and the UI locks the form). See below.
LEUMAS_OAUTH_REDIRECT_URIPins the callback URI. Otherwise it is derived from the address the browser is at — env → X-Forwarded-HostOriginRefererHost — never from the listening socket, because in dev the browser is on Vite and 127.0.0.1 and localhost are different origins to Google.

Pinned vs shared OAuth apps

Two modes, opposite failure modes, both real — so it is a flag rather than a flip:

  • Pinned (default). Env wins outright and the provider shows as locked. An operator must not be

able to silently repoint a fleet's or a vendor's Google app by saving a row over it.

  • Shared (LEUMAS_OAUTH_SHARED_APPS=1). Env is Leumas's own registered app, offered so a new

Studio can connect an account with no OAuth paperwork — and a tenant that registers their own app beats it. status() reports shared: true (works today, not locked) or overrides: 'shared' (your own app is the one in use).

A tenant's own app is the better one whenever it exists: their name on the consent screen, their quota, and no shared-app suspension taking them down with it.

Source shared/engines/connectors/README.md (no-git)markdownjson
Generated from the Leumas repository. Every page cites the file it came from.leumas.techllms.txt