@atlasauth/backend 0.10.0 → 0.12.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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @atlasauth/backend changelog
2
2
 
3
+ ## 0.12.0
4
+ - **Referral attribution v2.** `referrals.retryFailed({ kind?, error_code? }, idempotencyKey?)` (`POST /v1/instance/referrals/calls/retry_failed`, `ReferralRetryFailedResult` with `requeued`), `referrals.simulate({ code? })` (`POST /v1/instance/referrals/simulate`, `ReferralSimulateResult`: `call_id`, `customer_ref`, `result`, `response`), `referrals.backfill({ since, codes?, code_metadata_path? }, idempotencyKey?)` and `referrals.getBackfill(id)` (`POST /v1/instance/referrals/backfill`, `GET /v1/instance/referrals/backfill/:id`, `ReferralBackfillJob`: `users_scanned`, `users_skipped`, `calls_queued`, `truncated`, `next_since`, `calls`), and `referrals.getForUser(userId)` (`GET /v1/users/:id/referral`, `UserReferralResult`).
5
+ - **Settings.** `ReferralSettings` and `UpdateReferralSettingsBody` gain `tracking_token`, `code_lookup_url`, `signup_code_field`, `forward_lifecycle`, `mirror_to_public_metadata` and `include_referral_claims`. `provider` can be `referally`. `ReferralProviderCapabilities` gains `alias`, `user` and `ping`; `needs` can list `tracking_token`. `ReferralConnectionStatus` gains `last_ping` (`ReferralPing`) and `alert` (`signature_rejected` or `connection_paused`). `ReferralConnectionTest` gains `ping`, `method` and `warnings`.
6
+ - **Call log.** `ReferralCallKind` adds `alias`, `user` and `ping`. `ReferralCall` gains `latency_ms`, `error_code`, `response`, `highlights`, `request_id` and `batch_id`. `ListReferralCallsParams` gains `error_code` and `starting_after`; `limit` goes up to 1000.
7
+ - **Users.** `users.setExternalId(id, externalId | null)` (`PATCH /v1/users/:id`); with referrals on, Atlas forwards the change to the platform as an alias. `UpdateUserBody` gains `external_id`. `UserReferral` gains `partner_external_ref`, `referral_status` and `notes`; `status` is now the attribution status (`pending`, `attributed`, `none`, `failed`, `held`, `flagged`), and the platform's own status moved to `referral_status`. New `UserReferralResolvedEvent` types the `data` of `user.referral_resolved`.
8
+ - **before_user_create hook.** New `userHooks` namespace: `getBeforeUserCreate()`, `updateBeforeUserCreate(body)` and `testBeforeUserCreate()` (`/v1/instance/hooks/before_user_create`; `BeforeUserCreateHook`, `UpdateBeforeUserCreateHookBody`, `BeforeUserCreateHookTest`).
9
+ - **Referral protocol receiver.** `verifyReferralRequest` accepts the new operations `alias` (`/aliases`, `ReferralAliasPayload`), `user` (`/users`, `ReferralUserPayload`) and `ping` (`/ping`, `ReferralPingPayload`; answer `ReferralPingResponse`), and returns `protocolVersion` (the `Atlas-Referrals-Version` header). `ReferralSignupResponse` gains optional `notes`. New constants `REFERRAL_PROTOCOL_VERSION` (`2026-10-21`) and `REFERRAL_PROTOCOL_VERSION_HEADER`.
10
+ - **Test calls.** `createTestIssuer()` gains `referralCall(options)` (an Atlas referral protocol call, signed as an instance signs it) and `referallyCall(options)` (a Referally connection call: `x-referally-signature` over the raw body, or the raw query string for `export`, with `referally-version`). Also standalone: `signAtlasReferralCall`, `signReferallyCall`, `referallySignature`, `referralEmailHash`, `REFERALLY_API_VERSION`; types `SignedReferralCall`, `AtlasReferralCallOptions`, `ReferallyCallOptions`, `ReferallyCallOp`.
11
+ - **Compatible.** New methods, types, optional fields and constants. One meaning changed on the server: `user.referral.status` is the attribution status; read the platform's status from `referral_status`.
12
+
13
+ ## 0.11.0
14
+ - **Referral attribution settings.** New `referrals` namespace: `get()` and `update(body, idempotencyKey?)` (`GET`/`PATCH /v1/instance/referrals`; `ReferralSettings`, `UpdateReferralSettingsBody` with nested `security`: `ReferralSecuritySettings` `challenge_referred_signups`, `on_high_risk`, `hold_until_email_verified`, `max_referred_signups_per_ip_hour`), `test()` (`ReferralConnectionTest`), `listCalls({ limit?, status?, kind?, user_id? })` (`ReferralCall`, `ListReferralCallsParams`) and `retryCall(id, idempotencyKey?)`. Also `ReferralProviderInfo`, `ReferralProviderCapabilities`, `ReferralConnectionStatus`, `ReferralRisk`, `ReferralCallKind`, `ReferralCallStatus`.
15
+ - **Users.** `User` gains optional `referral` (`UserReferral`: `partner_id`, `referrer_external_id`, `referrer_user_id`, `matched_via`, `status`, `risk_level`, `flagged`), `referral_code` and `referral_link`. `CreateUserBody` accepts `referral` (`CreateUserReferralInput`: `code`, `click_id`, `anon_id`) and `referral_code`; `UpdateUserBody` accepts `referral_code` (`null` clears). New `users.flagReferral(id, { reason? }, idempotencyKey?)` (`POST /v1/users/:id/referral/flag`, `UserReferralFlag`).
16
+ - **Webhooks.** `UserReferralAttributedEvent` types the `data` of the new `user.referral_attributed` event (the referral platform answered after `user.created`).
17
+ - **Error codes.** `AtlasErrorCodes` adds `REFERRALS_NOT_CONFIGURED` (422) and `REFERRAL_CODE_TAKEN` (409). Preflight can report `referrals_enabled_unverified` and `referrals_without_bot_protection`.
18
+ - **Referral protocol receiver.** `verifyReferralRequest({ body, headers, secret, path?, expectedOp?, now?, toleranceMs? })` verifies a call from Atlas to a referral platform (the webhook signature scheme; every call is a `POST` whose signed body carries `op` and `customerRef`) and returns `call` by operation (`ReferralProtocolCall`: `signup`, `erase`, `export` with `test`, `partner`, `signal`), plus `deliveryId`, `timestamp` and `idempotencyKey`. It refuses (`ReferralVerifyFailure`) a body that is not an object (`malformed_body`), a missing or unknown `op` (`missing_op`, `unknown_op`), a path that is not a protocol endpoint (`unknown_endpoint`) and an `op` that does not match the path or `expectedOp` (`op_mismatch`). Payload types: `ReferralSignupPayload`, `ReferralSignupResponse`, `ReferralErasePayload`, `ReferralExportPayload`, `ReferralPartnerPayload`, `ReferralSignalPayload`, `ReferralSignalType`, `ReferralContext`, `ReferralRiskVerdict`, `ReferralOp`; `referralOpForPath`; constants `REFERRAL_OP_ENDPOINTS`, `REFERRAL_CONNECTION_TEST_REF`, `REFERRAL_PROTOCOL_USER_AGENT`.
19
+ - **Compatible.** New methods, types, optional fields and constants only.
20
+
3
21
  ## 0.10.0
4
22
  - **Trusted reverse proxy secret.** `instanceSecurity.getProxySecret()` (`ProxySecret`: `set`, `created_at`, `previous_expires_at`, `secret_header`, `client_ip_header`), `instanceSecurity.createProxySecret({ overlap_seconds? })` (`ProxySecretCreated`: adds `secret`, shown once, and `rotated`; `CreateProxySecretBody`) and `instanceSecurity.deleteProxySecret()`. A proxy that serves the Frontend API from your own origin sends the secret in `X-Atlas-Proxy-Secret` and the browser's IP in `X-Atlas-Client-IP`; Atlas then uses that IP for rate limits, lockout, risk signals, geo, audit logs and session metadata.
5
23
  - **Managed email feedback on Resend.** `ManagedEmail.feedback_webhook` is now also returned for Resend (on create and verify): Atlas registers a bounce / complaint webhook on your own Resend account, so `usage.bounces` / `usage.complaints` count for Resend domains too.
package/README.md CHANGED
@@ -401,3 +401,58 @@ To check the route end to end, `oauthClients.testBackchannelLogout(id)` sends a
401
401
  `verifyWebhook` checks the signature on events Atlas sends to your webhook endpoints. You manage endpoints with `atlas.webhooks.endpoints`: create, update, reveal or rotate a secret, send a test event, and redeliver a past delivery.
402
402
 
403
403
  The `atlas-signature` header can carry more than one signature, separated by spaces (`v1,<sig> v1,<sig>`). While an endpoint secret rotates, Atlas may sign each delivery with the old and the new secret. `verifyWebhook` accepts the delivery when any one signature matches your secret.
404
+
405
+ ## Referral attribution
406
+
407
+ With referral attribution on, Atlas reports every interactive sign-up to your referral platform before `user.created` is sent. The answer lands on the user: `referral` (who referred them, or null), `referral_code` and `referral_link` (the user's own code and link, when they are a referrer).
408
+
409
+ ```ts
410
+ await atlas.referrals.update({
411
+ enabled: true,
412
+ provider: 'webhook', // the Atlas referral protocol; or a built-in vendor adapter
413
+ endpoint_url: 'https://referrals.example.com/atlas',
414
+ signing_secret: process.env.REFERRAL_SIGNING_SECRET,
415
+ auto_enroll_users: true,
416
+ link_template: 'https://app.example.com/join?ref={code}',
417
+ security: { on_high_risk: 'hold' },
418
+ });
419
+ const test = await atlas.referrals.test(); // { ok, http_status, latency_ms, error? }
420
+ const failed = await atlas.referrals.listCalls({ status: 'failed', limit: 20 });
421
+ await atlas.referrals.retryCall(failed.data[0]!.id);
422
+
423
+ const user = await atlas.users.get('user_123');
424
+ user.referral?.referrer_user_id;
425
+ await atlas.users.update('user_123', { referral_code: 'ada-1' }); // 409 REFERRAL_CODE_TAKEN if held
426
+ await atlas.users.flagReferral('user_123', { reason: 'self-referral' });
427
+ ```
428
+
429
+ Enabling without what the provider needs is `422 REFERRALS_NOT_CONFIGURED`. When the platform answers late, Atlas sends the `user.referral_attributed` webhook (`UserReferralAttributedEvent`). Preflight may report `referrals_enabled_unverified` and `referrals_without_bot_protection`.
430
+
431
+ ### Receive the referral protocol (referral platforms)
432
+
433
+ A referral platform that implements the Atlas referral protocol verifies Atlas's calls with `verifyReferralRequest`. Every call is a `POST` signed like a webhook, and its JSON body says which operation it is (`op`): `signup`, `erase`, `export`, `partner` or `signal`. Pass the path the call arrived on: a signed body whose `op` does not match the endpoint is refused (`op_mismatch`).
434
+
435
+ ```ts
436
+ import { verifyReferralRequest } from '@atlasauth/backend';
437
+
438
+ app.post('/atlas/:endpoint', express.raw({ type: '*/*' }), async (req, res) => {
439
+ const { verified, call } = verifyReferralRequest({
440
+ body: req.body,
441
+ headers: req.headers,
442
+ secret: process.env.REFERRAL_SIGNING_SECRET!,
443
+ path: req.path, // or expectedOp: 'signup' on a handler for one endpoint
444
+ });
445
+ if (!verified || !call) return res.sendStatus(401);
446
+ switch (call.op) {
447
+ case 'signup': // ReferralSignupPayload → answer ReferralSignupResponse
448
+ return res.json({ referral: await match(call.payload), partner: await enroll(call.payload) });
449
+ case 'export': // the connection test sends test: true
450
+ return call.test ? res.sendStatus(404) : res.json(await exportFor(call.payload.customerRef));
451
+ default: // erase, partner, signal
452
+ await handle(call);
453
+ return res.sendStatus(204);
454
+ }
455
+ });
456
+ ```
457
+
458
+ A retry of one call keeps its `atlas-id` (`deliveryId`). Sign-ups are idempotent on `customerRef`: answer a retry the same way.
@@ -57,6 +57,10 @@ export declare const AtlasErrorCodes: {
57
57
  readonly DEVELOPMENT_EMAIL_LIMIT_REACHED: "DEVELOPMENT_EMAIL_LIMIT_REACHED";
58
58
  /** 422 — the development sender sends only Atlas's own sign-in emails, never custom templates. */
59
59
  readonly DEVELOPMENT_EMAIL_TEMPLATE_NOT_ALLOWED: "DEVELOPMENT_EMAIL_TEMPLATE_NOT_ALLOWED";
60
+ /** 422 — referrals cannot be enabled until the provider's needs are set (`meta` names what is missing). */
61
+ readonly REFERRALS_NOT_CONFIGURED: "REFERRALS_NOT_CONFIGURED";
62
+ /** 409 — another user on the instance already holds that referral code. */
63
+ readonly REFERRAL_CODE_TAKEN: "REFERRAL_CODE_TAKEN";
60
64
  /** The billing plan still has subscribers and cannot be removed. */
61
65
  readonly PLAN_IN_USE: "PLAN_IN_USE";
62
66
  /** The key is valid but for another API surface (e.g. a platform key on the Backend API). */
@@ -53,6 +53,10 @@ exports.AtlasErrorCodes = {
53
53
  DEVELOPMENT_EMAIL_LIMIT_REACHED: 'DEVELOPMENT_EMAIL_LIMIT_REACHED',
54
54
  /** 422 — the development sender sends only Atlas's own sign-in emails, never custom templates. */
55
55
  DEVELOPMENT_EMAIL_TEMPLATE_NOT_ALLOWED: 'DEVELOPMENT_EMAIL_TEMPLATE_NOT_ALLOWED',
56
+ /** 422 — referrals cannot be enabled until the provider's needs are set (`meta` names what is missing). */
57
+ REFERRALS_NOT_CONFIGURED: 'REFERRALS_NOT_CONFIGURED',
58
+ /** 409 — another user on the instance already holds that referral code. */
59
+ REFERRAL_CODE_TAKEN: 'REFERRAL_CODE_TAKEN',
56
60
  /** The billing plan still has subscribers and cannot be removed. */
57
61
  PLAN_IN_USE: 'PLAN_IN_USE',
58
62
  /** The key is valid but for another API surface (e.g. a platform key on the Backend API). */
@@ -1 +1 @@
1
- {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/client/error.ts"],"names":[],"mappings":";;;AAoBA,MAAa,aAAc,SAAQ,KAAK;IACpB,IAAI,GAAG,eAAe,CAAC;IACzC,0CAA0C;IACjC,MAAM,CAAS;IACxB,8CAA8C;IACrC,MAAM,CAAmB;IAElC,YAAY,MAAc,EAAE,MAAwB,EAAE,OAAgB;QACpE,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,wCAAwC,MAAM,EAAE,CAAC,CAAC;QACzF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,uEAAuE;QACvE,sEAAsE;QACtE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACvD,CAAC;IAED,uEAAuE;IACvE,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;IAC9B,CAAC;IAED,yEAAyE;IACzE,OAAO,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAClD,CAAC;CACF;AAzBD,sCAyBC;AAED;;;;GAIG;AACU,QAAA,eAAe,GAAG;IAC7B,+EAA+E;IAC/E,6BAA6B,EAAE,+BAA+B;IAC9D,mEAAmE;IACnE,uBAAuB,EAAE,yBAAyB;IAClD,oGAAoG;IACpG,qBAAqB,EAAE,uBAAuB;IAC9C,oGAAoG;IACpG,qBAAqB,EAAE,uBAAuB;IAC9C,wGAAwG;IACxG,cAAc,EAAE,gBAAgB;IAChC,0FAA0F;IAC1F,aAAa,EAAE,eAAe;IAC9B,uIAAuI;IACvI,eAAe,EAAE,iBAAiB;IAClC,oFAAoF;IACpF,6BAA6B,EAAE,+BAA+B;IAC9D,8EAA8E;IAC9E,6BAA6B,EAAE,+BAA+B;IAC9D,6HAA6H;IAC7H,+BAA+B,EAAE,iCAAiC;IAClE,kGAAkG;IAClG,sCAAsC,EAAE,wCAAwC;IAChF,oEAAoE;IACpE,WAAW,EAAE,aAAa;IAC1B,6FAA6F;IAC7F,iBAAiB,EAAE,mBAAmB;IACtC,gDAAgD;IAChD,WAAW,EAAE,aAAa;IAC1B,SAAS,EAAE,WAAW;IACtB,iBAAiB,EAAE,mBAAmB;IACtC,YAAY,EAAE,cAAc;IAC5B,4FAA4F;IAC5F,oBAAoB,EAAE,sBAAsB;IAC5C,yFAAyF;IACzF,cAAc,EAAE,gBAAgB;IAChC,eAAe,EAAE,iBAAiB;IAClC,oBAAoB,EAAE,sBAAsB;IAC5C,eAAe,EAAE,iBAAiB;IAClC,aAAa,EAAE,eAAe;IAC9B,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;CACZ,CAAC"}
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../src/client/error.ts"],"names":[],"mappings":";;;AAoBA,MAAa,aAAc,SAAQ,KAAK;IACpB,IAAI,GAAG,eAAe,CAAC;IACzC,0CAA0C;IACjC,MAAM,CAAS;IACxB,8CAA8C;IACrC,MAAM,CAAmB;IAElC,YAAY,MAAc,EAAE,MAAwB,EAAE,OAAgB;QACpE,KAAK,CAAC,OAAO,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,IAAI,wCAAwC,MAAM,EAAE,CAAC,CAAC;QACzF,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,uEAAuE;QACvE,sEAAsE;QACtE,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACvD,CAAC;IAED,uEAAuE;IACvE,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;IAC9B,CAAC;IAED,yEAAyE;IACzE,OAAO,CAAC,IAAY;QAClB,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAClD,CAAC;CACF;AAzBD,sCAyBC;AAED;;;;GAIG;AACU,QAAA,eAAe,GAAG;IAC7B,+EAA+E;IAC/E,6BAA6B,EAAE,+BAA+B;IAC9D,mEAAmE;IACnE,uBAAuB,EAAE,yBAAyB;IAClD,oGAAoG;IACpG,qBAAqB,EAAE,uBAAuB;IAC9C,oGAAoG;IACpG,qBAAqB,EAAE,uBAAuB;IAC9C,wGAAwG;IACxG,cAAc,EAAE,gBAAgB;IAChC,0FAA0F;IAC1F,aAAa,EAAE,eAAe;IAC9B,uIAAuI;IACvI,eAAe,EAAE,iBAAiB;IAClC,oFAAoF;IACpF,6BAA6B,EAAE,+BAA+B;IAC9D,8EAA8E;IAC9E,6BAA6B,EAAE,+BAA+B;IAC9D,6HAA6H;IAC7H,+BAA+B,EAAE,iCAAiC;IAClE,kGAAkG;IAClG,sCAAsC,EAAE,wCAAwC;IAChF,2GAA2G;IAC3G,wBAAwB,EAAE,0BAA0B;IACpD,2EAA2E;IAC3E,mBAAmB,EAAE,qBAAqB;IAC1C,oEAAoE;IACpE,WAAW,EAAE,aAAa;IAC1B,6FAA6F;IAC7F,iBAAiB,EAAE,mBAAmB;IACtC,gDAAgD;IAChD,WAAW,EAAE,aAAa;IAC1B,SAAS,EAAE,WAAW;IACtB,iBAAiB,EAAE,mBAAmB;IACtC,YAAY,EAAE,cAAc;IAC5B,4FAA4F;IAC5F,oBAAoB,EAAE,sBAAsB;IAC5C,yFAAyF;IACzF,cAAc,EAAE,gBAAgB;IAChC,eAAe,EAAE,iBAAiB;IAClC,oBAAoB,EAAE,sBAAsB;IAC5C,eAAe,EAAE,iBAAiB;IAClC,aAAa,EAAE,eAAe;IAC9B,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,UAAU;CACZ,CAAC"}
@@ -16,6 +16,7 @@ declare function buildNamespaces(request: RequestFn): {
16
16
  get(id: string): Promise<import("./users").User>;
17
17
  create(body: import("./users").CreateUserBody, idempotencyKey?: string): Promise<import("./users").User>;
18
18
  update(id: string, body: import("./users").UpdateUserBody): Promise<import("./users").User>;
19
+ setExternalId(id: string, externalId: string | null): Promise<import("./users").User>;
19
20
  replaceMetadata(id: string, body: import("./users").ReplaceUserMetadataBody): Promise<import("./users").User>;
20
21
  ban(id: string): Promise<import("./users").User>;
21
22
  unban(id: string): Promise<import("./users").User>;
@@ -23,6 +24,9 @@ declare function buildNamespaces(request: RequestFn): {
23
24
  duration_in_seconds?: number;
24
25
  }): Promise<import("./users").User>;
25
26
  unlock(id: string): Promise<import("./users").User>;
27
+ flagReferral(id: string, body?: {
28
+ reason?: string;
29
+ }, idempotencyKey?: string): Promise<import("./users").UserReferralFlag>;
26
30
  delete(id: string): Promise<import("./types").DeletedObject>;
27
31
  resetMfa(id: string): Promise<{
28
32
  object: "user";
@@ -970,6 +974,28 @@ declare function buildNamespaces(request: RequestFn): {
970
974
  deleted: true;
971
975
  }>;
972
976
  };
977
+ referrals: {
978
+ get(): Promise<import("./referrals").ReferralSettings>;
979
+ update(body: import("./referrals").UpdateReferralSettingsBody, idempotencyKey?: string): Promise<import("./referrals").ReferralSettings>;
980
+ test(): Promise<import("./referrals").ReferralConnectionTest>;
981
+ listCalls(params?: import("./referrals").ListReferralCallsParams): Promise<import("./types").ListPage<import("./referrals").ReferralCall>>;
982
+ retryCall(id: string, idempotencyKey?: string): Promise<import("./referrals").ReferralCall>;
983
+ retryFailed(filter?: {
984
+ kind?: import("./referrals").ReferralCallKind;
985
+ error_code?: string;
986
+ }, idempotencyKey?: string): Promise<import("./referrals").ReferralRetryFailedResult>;
987
+ simulate(body?: {
988
+ code?: string;
989
+ }): Promise<import("./referrals").ReferralSimulateResult>;
990
+ backfill(body: import("./referrals").ReferralBackfillBody, idempotencyKey?: string): Promise<import("./referrals").ReferralBackfillJob>;
991
+ getBackfill(id: string): Promise<import("./referrals").ReferralBackfillJob>;
992
+ getForUser(userId: string): Promise<import("./users").UserReferralResult>;
993
+ };
994
+ userHooks: {
995
+ getBeforeUserCreate(): Promise<import("./user-hooks").BeforeUserCreateHook>;
996
+ updateBeforeUserCreate(body: import("./user-hooks").UpdateBeforeUserCreateHookBody): Promise<import("./user-hooks").BeforeUserCreateHook>;
997
+ testBeforeUserCreate(): Promise<import("./user-hooks").BeforeUserCreateHookTest>;
998
+ };
973
999
  tokens: {
974
1000
  verify(body: import("./tokens").VerifyTokenBody): Promise<import("./tokens").TokenVerification>;
975
1001
  };
@@ -1320,6 +1346,8 @@ export * from './radius-clients';
1320
1346
  export * from './lti-platforms';
1321
1347
  export * from './instance';
1322
1348
  export * from './instance-security';
1349
+ export * from './referrals';
1350
+ export * from './user-hooks';
1323
1351
  export * from './tokens';
1324
1352
  export * from './captcha';
1325
1353
  export * from './design';
@@ -60,6 +60,8 @@ const radius_clients_1 = require("./radius-clients");
60
60
  const lti_platforms_1 = require("./lti-platforms");
61
61
  const instance_1 = require("./instance");
62
62
  const instance_security_1 = require("./instance-security");
63
+ const referrals_1 = require("./referrals");
64
+ const user_hooks_1 = require("./user-hooks");
63
65
  const tokens_1 = require("./tokens");
64
66
  const captcha_1 = require("./captcha");
65
67
  const design_1 = require("./design");
@@ -147,6 +149,10 @@ function buildNamespaces(request) {
147
149
  ltiPlatforms: (0, lti_platforms_1.ltiPlatformsResource)(request),
148
150
  instance: (0, instance_1.instanceResource)(request),
149
151
  instanceSecurity: (0, instance_security_1.instanceSecurityResource)(request),
152
+ // Referral attribution: the instance's referral platform connection and call log.
153
+ referrals: (0, referrals_1.referralsResource)(request),
154
+ // The before_user_create hook (sets external_id before the user exists).
155
+ userHooks: (0, user_hooks_1.userHooksResource)(request),
150
156
  tokens: (0, tokens_1.tokensResource)(request),
151
157
  // §5 "captcha anywhere" — verify any CAPTCHA token against the instance's
152
158
  // centrally-configured provider, server-side, with the secret held by Atlas.
@@ -236,6 +242,8 @@ __exportStar(require("./radius-clients"), exports);
236
242
  __exportStar(require("./lti-platforms"), exports);
237
243
  __exportStar(require("./instance"), exports);
238
244
  __exportStar(require("./instance-security"), exports);
245
+ __exportStar(require("./referrals"), exports);
246
+ __exportStar(require("./user-hooks"), exports);
239
247
  __exportStar(require("./tokens"), exports);
240
248
  __exportStar(require("./captcha"), exports);
241
249
  __exportStar(require("./design"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/client/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,405 @@
1
+ import { type RequestFn } from './request';
2
+ import type { ListPage } from './types';
3
+ import type { UserReferralResult } from './users';
4
+ /**
5
+ * Referral attribution: the instance's connection to a referral platform.
6
+ *
7
+ * With referrals on, every interactive sign-up is reported to the platform
8
+ * before `user.created` is sent and before the session is issued. The
9
+ * platform's answer lands on the user (`referral`, `referral_code`,
10
+ * `referral_link`). A slow or failing platform never fails a sign-up: the
11
+ * call is retried, and `user.referral_attributed` is sent when it resolves.
12
+ *
13
+ * `provider` is `webhook` (the Atlas referral protocol, which any platform can
14
+ * implement; see {@link verifyReferralRequest}), `referally` (the built-in
15
+ * Referally adapter: `endpoint_url` is your Referally base URL, plus
16
+ * `connection_id`, `signing_secret` and optionally `tracking_token`) or
17
+ * another built-in vendor adapter.
18
+ * `signing_secret` and `api_key` are write-only: reads return
19
+ * `signing_secret_set` / `api_key_set`.
20
+ */
21
+ /** What a provider can do. An operation it lacks is recorded as `skipped`. */
22
+ export interface ReferralProviderCapabilities {
23
+ signup: boolean;
24
+ erase: boolean;
25
+ export: boolean;
26
+ partner: boolean;
27
+ auto_enroll: boolean;
28
+ signal: boolean;
29
+ /** Forwards an `external_id` change after sign-up (old id → new id). */
30
+ alias?: boolean;
31
+ /** Forwards email, name and ban/unban changes. */
32
+ user?: boolean;
33
+ /** Answers a ping (org, program, clock) for the connection test. */
34
+ ping?: boolean;
35
+ }
36
+ /** A referral provider Atlas supports. */
37
+ export interface ReferralProviderInfo {
38
+ /** `webhook` (the Atlas referral protocol) or a vendor adapter id (`dub`, `firstpromoter`, …). */
39
+ id: string;
40
+ name: string;
41
+ capabilities: ReferralProviderCapabilities;
42
+ /** What must be set before `enabled` can be true. */
43
+ needs: Array<'endpoint_url' | 'signing_secret' | 'api_key' | 'connection_id' | 'tracking_token'>;
44
+ /** The vendor's own first-party tracking cookie, suggested when this provider is picked. */
45
+ default_context_cookie: string | null;
46
+ docs_url: string | null;
47
+ }
48
+ /** Fraud and bot protection for referred sign-ups (`security` on the settings). */
49
+ export interface ReferralSecuritySettings {
50
+ /**
51
+ * `always` (default): a sign-up carrying a referral code must pass the bot
52
+ * challenge, even where the captcha is otherwise off. `inherit`: the
53
+ * instance captcha policy decides. With no working captcha, `always` behaves
54
+ * as `inherit` and preflight reports `referrals_without_bot_protection`.
55
+ */
56
+ challenge_referred_signups: 'always' | 'inherit';
57
+ /**
58
+ * `flag` (default): report the sign-up with its risk. `strip`: report it as
59
+ * not referred, with `rejected.reason`. `hold`: report nothing until the
60
+ * email is proven, then re-assess.
61
+ */
62
+ on_high_risk: 'flag' | 'strip' | 'hold';
63
+ /** Hold every referred sign-up until the email is proven. Default false. */
64
+ hold_until_email_verified: boolean;
65
+ /** Referred sign-ups per code from one IP network or device per hour before a velocity signal (1-1000, default 5). */
66
+ max_referred_signups_per_ip_hour: number;
67
+ }
68
+ /** The connection's health, as the settings read reports it. */
69
+ export interface ReferralConnectionStatus {
70
+ /** The last connection test, or null when never tested. */
71
+ last_test: {
72
+ ok: boolean;
73
+ at: number;
74
+ http_status: number | null;
75
+ error: string | null;
76
+ } | null;
77
+ /** Calls that failed permanently in the last 7 days. */
78
+ failed_calls_7d: number;
79
+ /** Calls waiting for a retry. */
80
+ retrying_calls: number;
81
+ /** Epoch ms of the last successful call, or null. */
82
+ last_success_at: number | null;
83
+ /** The last ping answer, when the provider supports ping. */
84
+ last_ping?: ReferralPing | null;
85
+ /**
86
+ * A refusal only a person can fix: `signature_rejected` (the platform
87
+ * answered 401: a rotated secret or clock skew) or `connection_paused`.
88
+ */
89
+ alert?: {
90
+ code: string;
91
+ message: string;
92
+ at: number;
93
+ call_id?: string;
94
+ } | null;
95
+ }
96
+ /** What a platform answers to a ping. */
97
+ export interface ReferralPing {
98
+ ok: boolean;
99
+ connection_id?: string | null;
100
+ program_id?: string | null;
101
+ program_name?: string | null;
102
+ org_name?: string | null;
103
+ auto_enroll_users?: boolean | null;
104
+ /** The platform's clock, as it sent it. */
105
+ server_time?: string | number | null;
106
+ /** Platform clock minus Atlas clock, in ms. Over 60 s is a warning; over 5 minutes, signatures fail. */
107
+ clock_skew_ms?: number | null;
108
+ /** True when `clock_skew_ms` is over 60 seconds. */
109
+ clock_skew_warning?: boolean;
110
+ /** Epoch ms of the ping. */
111
+ at?: number | null;
112
+ http_status?: number | null;
113
+ latency_ms?: number | null;
114
+ error_code?: string | null;
115
+ error?: string | null;
116
+ }
117
+ /** `GET /v1/instance/referrals`. */
118
+ export interface ReferralSettings {
119
+ object: 'referral_settings';
120
+ enabled: boolean;
121
+ /** `webhook` (the Atlas referral protocol) or a built-in vendor adapter id. */
122
+ provider: string;
123
+ /** Base URL of the platform connection (Atlas referral protocol). */
124
+ endpoint_url: string | null;
125
+ /** Passed through to the platform. */
126
+ program_id: string | null;
127
+ /** Your label for the connection on the platform side. */
128
+ connection_id: string | null;
129
+ /** Whether a signing secret is stored (the value is never returned). */
130
+ signing_secret_set: boolean;
131
+ /** Whether a vendor API key is stored (the value is never returned). */
132
+ api_key_set: boolean;
133
+ /** Query parameters that carry a referral code, in priority order (default `ref`, `via`, `aff`). */
134
+ url_params: string[];
135
+ /** First-party tracking cookie read under consent; null = never read a cookie. */
136
+ context_cookie: string | null;
137
+ consent_category: string;
138
+ consent_fallback_category: string | null;
139
+ /** Every new user becomes a referrer (gets a code and link from the platform). */
140
+ auto_enroll_users: boolean;
141
+ /** e.g. `https://app.example.com/join?ref={code}`; builds `referral_link`. */
142
+ link_template: string | null;
143
+ /** How long a sign-up waits for the platform (100-5000 ms, default 3000). */
144
+ timeout_ms: number;
145
+ security: ReferralSecuritySettings;
146
+ /** Public tracking token (the `referally` adapter derives the code lookup from it). */
147
+ tracking_token?: string | null;
148
+ /** Public, CORS-enabled lookup with `{code}` for "X invited you" on hosted sign-up. */
149
+ code_lookup_url?: string | null;
150
+ /** Show an optional "Referral code" field on hosted sign-up. */
151
+ signup_code_field?: boolean;
152
+ /** Forward email, name and ban/unban changes to the platform (default true). */
153
+ forward_lifecycle?: boolean;
154
+ /** Mirror the result into `public_metadata.referral` (default false). */
155
+ mirror_to_public_metadata?: boolean;
156
+ /** Add a `referral_code` claim (the user's own code) to ID tokens and sessions. */
157
+ include_referral_claims?: boolean;
158
+ /** What the chosen provider still needs before referrals can be enabled. */
159
+ missing?: string[];
160
+ connection?: ReferralConnectionStatus | null;
161
+ providers: ReferralProviderInfo[];
162
+ updated_at?: number | null;
163
+ }
164
+ /**
165
+ * `PATCH /v1/instance/referrals`: only the fields sent change, `null` clears.
166
+ * Enabling without what the provider needs is `422 REFERRALS_NOT_CONFIGURED`.
167
+ */
168
+ export interface UpdateReferralSettingsBody {
169
+ enabled?: boolean;
170
+ provider?: string;
171
+ /** https only (http only for localhost on a development instance). */
172
+ endpoint_url?: string | null;
173
+ program_id?: string | null;
174
+ connection_id?: string | null;
175
+ /** Write-only, 16-512 characters. */
176
+ signing_secret?: string | null;
177
+ /** Write-only vendor API key. */
178
+ api_key?: string | null;
179
+ /** 1-10 names of `[A-Za-z0-9_.-]{1,40}`. */
180
+ url_params?: string[];
181
+ context_cookie?: string | null;
182
+ consent_category?: string;
183
+ consent_fallback_category?: string | null;
184
+ auto_enroll_users?: boolean;
185
+ /** An https URL containing `{code}`. */
186
+ link_template?: string | null;
187
+ /** 100-5000. */
188
+ timeout_ms?: number;
189
+ /** Partial: only the security fields sent change. */
190
+ security?: Partial<ReferralSecuritySettings>;
191
+ tracking_token?: string | null;
192
+ /** An https URL containing `{code}`. */
193
+ code_lookup_url?: string | null;
194
+ signup_code_field?: boolean;
195
+ forward_lifecycle?: boolean;
196
+ mirror_to_public_metadata?: boolean;
197
+ include_referral_claims?: boolean;
198
+ }
199
+ /** `POST /v1/instance/referrals/test`. */
200
+ export interface ReferralConnectionTest {
201
+ ok: boolean;
202
+ http_status?: number | null;
203
+ latency_ms?: number | null;
204
+ /** e.g. `signature_rejected` (the platform answered 401/403), `timeout`, `network_error`, `url_blocked`, `http_500`. */
205
+ error?: {
206
+ code: string;
207
+ message: string;
208
+ };
209
+ /** The ping answer, when the provider supports ping (the test is then a ping). */
210
+ ping?: ReferralPing | null;
211
+ /** `ping`, or `probe` (the older signed export probe). */
212
+ method?: 'ping' | 'probe';
213
+ /** Human warnings, e.g. a clock more than 60 seconds off. */
214
+ warnings?: string[];
215
+ }
216
+ /** `POST /v1/instance/referrals/simulate`: a sign-up call for a fake user, never stored. */
217
+ export interface ReferralSimulateResult {
218
+ object: 'referral_simulation';
219
+ ok: boolean;
220
+ /** The logged call, in the delivery log. */
221
+ call_id: string | null;
222
+ /** `atlas_test_<random>`. */
223
+ customer_ref: string;
224
+ http_status: number | null;
225
+ latency_ms: number | null;
226
+ /** The platform's answer, normalised (null when the call failed). */
227
+ result: {
228
+ referral: {
229
+ partner_id: string | null;
230
+ partner_external_ref: string | null;
231
+ matched_via: string | null;
232
+ status: string | null;
233
+ } | null;
234
+ partner: {
235
+ id: string | null;
236
+ code: string | null;
237
+ link: string | null;
238
+ } | null;
239
+ notes: string[];
240
+ } | null;
241
+ /** The platform's raw answer, personal fields removed. */
242
+ response: unknown;
243
+ error: {
244
+ code: string;
245
+ message: string;
246
+ } | null;
247
+ }
248
+ /** `POST /v1/instance/referrals/calls/retry_failed`. */
249
+ export interface ReferralRetryFailedResult {
250
+ object: 'referral_retry';
251
+ /** How many failed calls were queued to send now. */
252
+ requeued: number;
253
+ }
254
+ /** `POST /v1/instance/referrals/backfill`. */
255
+ export interface ReferralBackfillBody {
256
+ /** ISO 8601 date or date-time: users who signed up at or after it. */
257
+ since: string;
258
+ /** customerRef → code (a CSV, for example). Wins over `code_metadata_path`. */
259
+ codes?: Record<string, string>;
260
+ /** Where a stored code lives on the user, e.g. `public_metadata.referral_code`. */
261
+ code_metadata_path?: string;
262
+ }
263
+ /** A backfill job. Users already reported are skipped. */
264
+ export interface ReferralBackfillJob {
265
+ object: 'referral_backfill';
266
+ id: string;
267
+ /** `running` while any queued call is still to be sent, then `completed`. */
268
+ status: string;
269
+ /** Epoch ms. */
270
+ since: number;
271
+ code_metadata_path?: string | null;
272
+ /** How many codes were given in `codes`. */
273
+ codes_given?: number;
274
+ users_scanned: number;
275
+ /** Already reported, or no code while auto-enroll is off. */
276
+ users_skipped: number;
277
+ calls_queued: number;
278
+ /** True when the run stopped at its cap: start another from `next_since`. */
279
+ truncated: boolean;
280
+ /** Epoch ms, when `truncated`. */
281
+ next_since?: number | null;
282
+ /** Where the queued calls stand. */
283
+ calls: {
284
+ pending: number;
285
+ succeeded: number;
286
+ failed: number;
287
+ skipped: number;
288
+ held: number;
289
+ };
290
+ created_at: number;
291
+ finished_at?: number | null;
292
+ }
293
+ export type ReferralCallKind = 'signup' | 'erase' | 'export' | 'partner' | 'signal' | 'alias' | 'user' | 'ping' | 'test';
294
+ export type ReferralCallStatus = 'pending' | 'succeeded' | 'retrying' | 'failed' | 'held' | 'skipped';
295
+ /** The risk verdict sent with a sign-up (camelCase, as on the referral protocol). */
296
+ export interface ReferralRisk {
297
+ level: 'low' | 'medium' | 'high';
298
+ /** 0-100. */
299
+ score: number;
300
+ /**
301
+ * e.g. `self_referral`, `ip_velocity`, `device_velocity`, `disposable_email`,
302
+ * `datacenter_ip`, `tor_ip`, `captcha_not_passed`, `email_unverified`,
303
+ * `restricted_identifier`.
304
+ */
305
+ signals: string[];
306
+ captcha: 'passed' | 'not_required' | 'not_configured';
307
+ emailVerified: boolean;
308
+ }
309
+ /** One call in the referral call log. */
310
+ export interface ReferralCall {
311
+ object: 'referral_call';
312
+ /** Also the signed `atlas-id` header of every attempt. */
313
+ id: string;
314
+ kind: ReferralCallKind;
315
+ status: ReferralCallStatus;
316
+ /** Sign-up calls: `referred`, `not_referred` or `stripped`. */
317
+ outcome?: string | null;
318
+ customer_ref: string;
319
+ user_id?: string | null;
320
+ http_status?: number | null;
321
+ last_error?: string | null;
322
+ attempts: number;
323
+ /** Epoch ms of the next retry, while pending or retrying. */
324
+ next_attempt_at?: number | null;
325
+ risk?: ReferralRisk | null;
326
+ /** What was sent (never secrets). */
327
+ payload?: Record<string, unknown>;
328
+ /** Round trip of the last attempt, in ms. */
329
+ latency_ms?: number | null;
330
+ /**
331
+ * Machine code of the last failure, e.g. `signature_rejected` (401, not
332
+ * retried), `connection_paused` (paused by the merchant, not retried),
333
+ * `rate_limited`, `timeout`, `network_error`.
334
+ */
335
+ error_code?: string | null;
336
+ /** The platform's last answer, with personal data removed. */
337
+ response?: unknown;
338
+ /** Sign-up calls: how the platform matched, the referrer and its notes. */
339
+ highlights?: {
340
+ matched_via: string | null;
341
+ partner_external_ref: string | null;
342
+ notes: string[];
343
+ } | null;
344
+ /** The platform's request id for its last answer, for its support team. */
345
+ request_id?: string | null;
346
+ /** The backfill job this call belongs to. */
347
+ batch_id?: string | null;
348
+ created_at: number;
349
+ updated_at?: number;
350
+ }
351
+ export interface ListReferralCallsParams {
352
+ /** 1-1000 (1-200 on servers before referral attribution v2), default 50, newest first. */
353
+ limit?: number;
354
+ status?: ReferralCallStatus;
355
+ kind?: ReferralCallKind;
356
+ user_id?: string;
357
+ /** e.g. `signature_rejected`. */
358
+ error_code?: string;
359
+ /** The id of the last call of the previous page. */
360
+ starting_after?: string;
361
+ }
362
+ export declare function referralsResource(request: RequestFn): {
363
+ /** `GET /v1/instance/referrals` — settings, connection status and the supported providers. */
364
+ get(): Promise<ReferralSettings>;
365
+ /** `PATCH /v1/instance/referrals` — partial update; secrets are write-only. */
366
+ update(body: UpdateReferralSettingsBody, idempotencyKey?: string): Promise<ReferralSettings>;
367
+ /**
368
+ * `POST /v1/instance/referrals/test` — a signed probe of the platform. `ok`
369
+ * when it answered 2xx or 404; `error.code` `signature_rejected` on 401/403.
370
+ */
371
+ test(): Promise<ReferralConnectionTest>;
372
+ /** `GET /v1/instance/referrals/calls` — the call log, newest first. */
373
+ listCalls(params?: ListReferralCallsParams): Promise<ListPage<ReferralCall>>;
374
+ /**
375
+ * `POST /v1/instance/referrals/calls/:id/retry` — retry a failed, retrying
376
+ * or skipped call now (a connection test cannot be retried).
377
+ */
378
+ retryCall(id: string, idempotencyKey?: string): Promise<ReferralCall>;
379
+ /** `POST /v1/instance/referrals/calls/retry_failed` — re-queue every failed call (not tests) to send now. */
380
+ retryFailed(filter?: {
381
+ kind?: ReferralCallKind;
382
+ error_code?: string;
383
+ }, idempotencyKey?: string): Promise<ReferralRetryFailedResult>;
384
+ /**
385
+ * `POST /v1/instance/referrals/simulate` — send a sign-up call for a fake
386
+ * user (`atlas_test_<random>`, never stored) with an optional code, and
387
+ * return what the platform answered.
388
+ */
389
+ simulate(body?: {
390
+ code?: string;
391
+ }): Promise<ReferralSimulateResult>;
392
+ /**
393
+ * `POST /v1/instance/referrals/backfill` — queue sign-up calls for existing
394
+ * users with their real sign-up time. Referrals must be on (`422
395
+ * REFERRALS_NOT_CONFIGURED` otherwise). Returns the job; poll {@link getBackfill}.
396
+ */
397
+ backfill(body: ReferralBackfillBody, idempotencyKey?: string): Promise<ReferralBackfillJob>;
398
+ /** `GET /v1/instance/referrals/backfill/:id`. */
399
+ getBackfill(id: string): Promise<ReferralBackfillJob>;
400
+ /**
401
+ * `GET /v1/users/:id/referral` — the stored result for one user (who
402
+ * referred them, how, their own code), with no call to the platform.
403
+ */
404
+ getForUser(userId: string): Promise<UserReferralResult>;
405
+ };