@sprigr/apps-app-sdk 0.23.0 → 0.25.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 +2 -0
- package/dist/index.d.ts +73 -1
- package/dist/index.js +48 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -75,11 +75,13 @@ export default {
|
|
|
75
75
|
- `fetchWithRetry` — rate-limit-header-aware, jittered retry
|
|
76
76
|
- `constantTimeEqual(a, b)` — bearer-secret verification
|
|
77
77
|
- `encodeState` / `decodeState` — OAuth state base64url
|
|
78
|
+
- `encodeStateWithinEnvelope(state, { installId, appSlug, optional? })` — `encodeState` that leaves room for the platform's signed envelope (500 chars, decision 0190). An optional field (default `returnTo`) that does not fit is left out whole, never shortened, with a `console.warn` naming the lengths; without `returnTo` the bouncer lands the user on the install's dashboard. Use it for any state that carries a caller-supplied value. `oauthStateEnvelopeOverhead` and `OAUTH_STATE_ENVELOPE_MAX_CHARS` expose the arithmetic.
|
|
78
79
|
- `parseActor` / `actorKey` / `ownerFromActorKey` — per-actor token scoping
|
|
79
80
|
- `putAppFile` / `putAppFileStream` / `appFileUrl` / `getAppFile` / `listAppFiles` / `deleteAppFile` — durable app-scoped file storage from outside the injected bridge
|
|
80
81
|
- `fetchFileBytes` / `fetchFileAsBase64` / `bytesToBase64` / `base64ToBytes` — file byte helpers
|
|
81
82
|
- `readableStoredKey(appKey, downloadUrl)` / `agentFileKeyFromUrl` — turn the install-relative key your app stored a file under into the absolute key the platform's `read_file` tool opens (read off the signed URL `appFileUrl` minted). Return it as a tool's `file_key` so an agent can open the file. `appKeyFromCallerKey` / `callerKeyRefusal` go the other way, for a key an agent hands back to your tool (0.17.0)
|
|
82
83
|
- `readFileRef(env, { file_key } | { file_url }, { maxBytes })` / `resolveFileRef`: accept a file an agent hands your tool. `resolveFileRef` only validates (run it before an approval card): a key in this install's store in any form, or an https link on `files.sprigr.com` (a link into this install is read as its key; a company link must be signed and in this company; workspace keys, other installs and every other host are refused with a `FileRefError` whose message says what to pass instead). `readFileRef` then reads the bytes with a size cap, a 20 s time cap and no redirects; `openFileRef` does the same as a stream, for a large attachment passed on without buffering. `FILE_REF_SOURCES_HELP` is the agent-facing list of accepted sources, for a tool's input description (0.21.0)
|
|
84
|
+
- `getCompanyTimezone(env)`: the company's IANA zone from the platform's `COMPANY_TIMEZONE` binding, or `undefined` when the company has none or the value is not a zone `Intl` accepts. Never throws and never defaults; the app picks its own fallback (0.24.0)
|
|
83
85
|
|
|
84
86
|
Full platform semantics: [`docs/platform-reference.md`](../../docs/platform-reference.md).
|
|
85
87
|
|
package/dist/index.d.ts
CHANGED
|
@@ -74,6 +74,53 @@ interface OAuthState {
|
|
|
74
74
|
}
|
|
75
75
|
declare function encodeState(state: OAuthState): string;
|
|
76
76
|
declare function decodeState(encoded: string): OAuthState;
|
|
77
|
+
/**
|
|
78
|
+
* Longest platform-signed state the platform sends to a provider. Dropbox
|
|
79
|
+
* documents 500 bytes, the tightest cap among the marketplace's providers.
|
|
80
|
+
* Mirrors OAUTH_STATE_ENVELOPE_MAX_CHARS in sprigr-team
|
|
81
|
+
* packages/shared/src/utils/oauth-state-envelope.ts (decision 0190): a state
|
|
82
|
+
* whose envelope would pass it is sent UNSIGNED, and a slug on the bouncer's
|
|
83
|
+
* enforce list then refuses the connect.
|
|
84
|
+
*/
|
|
85
|
+
declare const OAUTH_STATE_ENVELOPE_MAX_CHARS = 500;
|
|
86
|
+
/**
|
|
87
|
+
* Characters the platform's signed envelope adds around an app's state.
|
|
88
|
+
* The wire shape is `sps1.<inner>.<payload>.<sig>`: payload is base64url JSON
|
|
89
|
+
* `{ i: installId, a: appSlug, t: <ms> }` and sig is 16 HMAC bytes, 22
|
|
90
|
+
* base64url characters (mintOAuthStateEnvelope in sprigr-team). `t` is the
|
|
91
|
+
* platform's signing time; any 13-digit ms timestamp gives the same length.
|
|
92
|
+
*/
|
|
93
|
+
declare function oauthStateEnvelopeOverhead(installId: string, appSlug: string, t?: number): number;
|
|
94
|
+
interface EncodeStateWithinEnvelopeOptions {
|
|
95
|
+
/** The install the platform signs into the envelope (env.INSTALL_ID). */
|
|
96
|
+
installId: string;
|
|
97
|
+
/** This app's marketplace slug, also signed into the envelope. */
|
|
98
|
+
appSlug: string;
|
|
99
|
+
/**
|
|
100
|
+
* Fields that may be left out, WHOLE, when the state would not fit, tried
|
|
101
|
+
* in this order. Default `['returnTo']`. List only fields the callback can
|
|
102
|
+
* do without: without returnTo the bouncer lands the user on the install's
|
|
103
|
+
* dashboard instead of the requested page.
|
|
104
|
+
*/
|
|
105
|
+
optional?: ReadonlyArray<keyof OAuthState>;
|
|
106
|
+
}
|
|
107
|
+
interface EncodedStateWithinEnvelope {
|
|
108
|
+
/** The encoded state to put on the authorize URL. */
|
|
109
|
+
state: string;
|
|
110
|
+
/** Optional fields left out to make it fit, in the order they were dropped. */
|
|
111
|
+
omitted: string[];
|
|
112
|
+
/** False when even the state without its optional fields is too long; it is then returned in full and the platform will send it unsigned. */
|
|
113
|
+
fits: boolean;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* encodeState, but leaving room for the platform's signed envelope
|
|
117
|
+
* (sprigr-apps#3190). An optional field that does not fit is left out whole,
|
|
118
|
+
* never shortened: a cut returnTo is a broken landing page, and an absent one
|
|
119
|
+
* falls back to the install's dashboard. Each omission is logged with the
|
|
120
|
+
* field's length and the state's length before and after, so the cause of a
|
|
121
|
+
* dashboard landing is findable.
|
|
122
|
+
*/
|
|
123
|
+
declare function encodeStateWithinEnvelope(state: OAuthState, opts: EncodeStateWithinEnvelopeOptions): EncodedStateWithinEnvelope;
|
|
77
124
|
|
|
78
125
|
/**
|
|
79
126
|
* fetchWithRetry — rate-limit-header-aware retry wrapper around fetch.
|
|
@@ -2924,6 +2971,31 @@ declare function purgeIndexByPrefix(env: WfpBridgeEnv, prefixes: readonly IdPref
|
|
|
2924
2971
|
chunk?: number;
|
|
2925
2972
|
}): Promise<PurgeResult>;
|
|
2926
2973
|
|
|
2974
|
+
/**
|
|
2975
|
+
* The install's company, as the platform binds it (sprigr-team#11006).
|
|
2976
|
+
*
|
|
2977
|
+
* `COMPANY_TIMEZONE` is a plain_text binding stamped at upload
|
|
2978
|
+
* (sprigr-team#11038): the company's IANA zone, so an app can compute the
|
|
2979
|
+
* tenant's "today" or a local cut-off without guessing. The platform binds it
|
|
2980
|
+
* only when the company has a valid zone, and never a default, so an install
|
|
2981
|
+
* whose company has none simply has no binding. A value written before a
|
|
2982
|
+
* zone change stays until the install's next build.
|
|
2983
|
+
*/
|
|
2984
|
+
/** The env slice this module reads. Optional: older installs lack it. */
|
|
2985
|
+
interface CompanyTimezoneEnv {
|
|
2986
|
+
COMPANY_TIMEZONE?: string;
|
|
2987
|
+
}
|
|
2988
|
+
/**
|
|
2989
|
+
* The company's IANA zone, or `undefined` when there is none.
|
|
2990
|
+
*
|
|
2991
|
+
* Returns the bound value (trimmed) only when `Intl` accepts it as a time
|
|
2992
|
+
* zone, so the result can be handed straight to `Intl.DateTimeFormat`. Never
|
|
2993
|
+
* throws and never invents a zone: `undefined` means "the platform does not
|
|
2994
|
+
* know", and the app decides its own fallback (a per-user zone, UTC, or
|
|
2995
|
+
* asking).
|
|
2996
|
+
*/
|
|
2997
|
+
declare function getCompanyTimezone(env: CompanyTimezoneEnv | null | undefined): string | undefined;
|
|
2998
|
+
|
|
2927
2999
|
/**
|
|
2928
3000
|
* @sprigr/apps-app-sdk
|
|
2929
3001
|
*
|
|
@@ -3498,4 +3570,4 @@ interface ExecutionContextLike {
|
|
|
3498
3570
|
}
|
|
3499
3571
|
type HandlerFn<TArgs, TResult> = (args: TArgs, env: Record<string, unknown>, ctx?: ExecutionContextLike) => Promise<TResult>;
|
|
3500
3572
|
|
|
3501
|
-
export { ACTOR_RETIRED_HOOK_TOOL, ACTOR_RETIRE_REASONS, APPROVAL_GRANTED_KEY, APPROVAL_PREVIEW_MAX, APP_FILES_ROOT, APP_OWNER_SEGMENT, type Actor, type ActorRetireReason, type ActorRetired, type ActorRetiredHookBody, type ActorRetiredResult, type AppApprovalEnvelope, type AppFileListItem, type AppFileUrlArgs, type AppFileUrlResult, type AppFilesEnv, type AppToolEffectsDeclaration, type AppUndoEnvelope, type ApplyPoliciesOptions, type ApprovalCoverage, type ApprovalGateOptions, type ApprovalSpec, type ArchiveOfferOptions, type ArchiveOfferRefusal, type CallerKeyResolution, type CaptureJournal, type ConfirmCondition, type ConfirmRule, type ConfirmationPolicy, type ConnectCompleteRequest, type ConnectCompleteResult, type D1Like, type D1PreparedStatementLike, DATA_DELETE_MAX_IDS, DATA_PARTIAL_UPDATE_PATH, DEFAULT_EMIT_TIMEOUT_MS, DEFAULT_FILE_READ_TIMEOUT_MS, DEFAULT_LOG_TIMEOUT_MS, DEFAULT_MAX_FILE_BYTES, DEFAULT_MONEY_FIELDS, DEFAULT_WRITE_PREFIXES, type DataClient, type DataIdsOpts, type DataListIdsResult, type DataTransport, type DerivePolicyOptions, type DerivedPolicy, type DispatcherApprovalGate, type DispatcherApprovalOptions, type EmitMarketplaceEventOptions, type EmitResult, type EmitTransport, type EventArgs, type ExecutionContextLike, FILE_REF_SOURCES_HELP, type FetchFileResult, type FetchWithRetryOptions, type FileRef, type FileRefContent, type FileRefEnv, FileRefError, type FileRefErrorCode, type FileRefStream, type FileRefVia, type GetAppFileResult, type HandlerFn, INBOX_SEND_CONTRACT_V1, type IdPrefixSpec, type IdSnapshot, type InboxAddress, type InboxAppendRequest, type InboxAppendResult, type InboxChannelDeclaration, type InboxFoldersRequest, type InboxFoldersResult, type InboxOwner, type InboxSendConnection, type InboxSendHandlerImpl, InboxSendRefusal, type InboxSendSupports, type InboxSendV1Args, type InboxSendV1Result, type InstallBridge, InvalidUndoEnvelopeError, type JournalRowLike, type LogToPlatformOptions, type ManifestDispatchBlock, type ManifestLike, type ManifestToolLike, type MarketplaceEventEmitOpts, type MarketplaceEventSourceIntegration, NotConnectedError, type OAuthBouncerSignals, type OAuthState, type OfferUndoArgs, type PartialUpdateDataOptions, type PlatformHostEnv, type PolicyCheckInput, type PolicySource, type PurgeResult, type PutAppFileArgs, type PutAppFileResult, type PutAppFileStreamArgs, type ReadFileRefOptions, type RequireApprovalOptions, type ResolveFileRefOptions, type ResolveViewerOptions, type ResolvedFileRef, type RestoreResult, type RestoreSpec, SPRIGR_DATA_MAX_OBJECTS_PER_CALL, SPRIGR_FILE_HOSTS, SPRIGR_LOG_LEVELS, SPRIGR_LOG_LIMITS, type ScheduleArgs, type SprigrDataAggregationCell, type SprigrDataAggregationResult, type SprigrDataAggregationSpec, type SprigrDataApi, type SprigrDataImportOpts, type SprigrDataIndexOpts, type SprigrDataPartialUpdateBody, type SprigrDataPartialUpdateOpts, type SprigrDataPartialUpdateResult, type SprigrDataPatch, type SprigrDataSearchOpts, type SprigrDataSearchResult, SprigrDataValidationError, type SprigrFilesApi, type SprigrFilesApiWithEdit, type SprigrFilesCreateInput, type SprigrFilesCreateResult, type SprigrFilesEditInput, type SprigrFilesEditResult, type SprigrFilesJobResult, type SprigrFilesListItem, type SprigrFilesListResult, type SprigrInboxApi, type SprigrLogEntry, type SprigrLogFn, type SprigrLogLevel, type SprigrLogResult, SprigrLogValidationError, type SyncedAttachment, type SyncedMessage, type ToolArgs, type ToolHandler, type ToolResult, type ToolWrapperOptions, UNIT_SEP, type UndoApplyOptions, type UndoApplyResult, type UndoCaptureSpec, type UndoFidelity, VIEWER_ANONYMOUS, VIEWER_CONTEXT_HEADER, VIEWER_PLATFORM_USER_ID_HEADER, VIEWER_ROLE_HEADER, VIEWER_USER_ID_HEADER, type VerbRule, type ViewerContext, type ViewerContextFailure, type ViewerContextVerification, type ViewerEnv, WORKSPACE_FILE_HOW_TO, type WebhookArgs, type WfpBridgeEnv, type WfpEmitReply, actorKey, actorRetiredHook, actorTool, agentFileKeyFromUrl, appFileUrl, appKeyFromCallerKey, applyConfirmationPolicies, approvalHash, approvalPreview, approvalRecipients, archiveOfferRefusal, attendedFindings, base64ToBytes, buildConfirmationPolicy, buildMarketplaceWebhookUrl, buildPartialUpdateBody, bytesToBase64, callerKeyRefusal, canEmit, canLog, canPartialUpdate, checkConfirmationPolicy, commonDestructiveVerbs, connectComplete, connectDisconnect, constantTimeEqual, createMarketplaceEmitter, createToolWrappers, decodeState, defineInboxSendHandler, deleteAppFile, deleteSnapshotIds, deriveConfirmationPolicy, describeMissingBridge, dispatcherApproval, emitMarketplaceEvent, encodeState, fetchFileAsBase64, fetchFileBytes, fetchWithRetry, fullWarning, getAppFile, hmacSha256Hex, installTokenPost, isNotConnectedError, isStagingHost, listAppFiles, logToPlatform, makeDataClient, manifestIsFresh, offerUndo, openFileRef, overlaySprigr, ownerFromActorKey, parseActor, parseActorRetiredArgs, partialUpdateData, purgeIndexByPrefix, putAppFile, putAppFileStream, randomHex, readFileRef, readableStoredKey, recreatedWarning, refuseWithoutForce, requireApproval, resolveFileRef, resolveInstallBridge, resolveOAuthBouncerBase, resolveOAuthBouncerCallbackUrl, resolvePlatformWebhookBase, resolveViewerContext, resolveViewerUserId, runUndoApply, safeCapture, seq, serializeManifest, set, snapshotIndexIds, tool, undoEnvelope, validateLogEntries, validateLogEntry, verifyViewerToken, withSprigrEmitFallback, withSprigrInboxFallback, withSprigrLogFallback };
|
|
3573
|
+
export { ACTOR_RETIRED_HOOK_TOOL, ACTOR_RETIRE_REASONS, APPROVAL_GRANTED_KEY, APPROVAL_PREVIEW_MAX, APP_FILES_ROOT, APP_OWNER_SEGMENT, type Actor, type ActorRetireReason, type ActorRetired, type ActorRetiredHookBody, type ActorRetiredResult, type AppApprovalEnvelope, type AppFileListItem, type AppFileUrlArgs, type AppFileUrlResult, type AppFilesEnv, type AppToolEffectsDeclaration, type AppUndoEnvelope, type ApplyPoliciesOptions, type ApprovalCoverage, type ApprovalGateOptions, type ApprovalSpec, type ArchiveOfferOptions, type ArchiveOfferRefusal, type CallerKeyResolution, type CaptureJournal, type CompanyTimezoneEnv, type ConfirmCondition, type ConfirmRule, type ConfirmationPolicy, type ConnectCompleteRequest, type ConnectCompleteResult, type D1Like, type D1PreparedStatementLike, DATA_DELETE_MAX_IDS, DATA_PARTIAL_UPDATE_PATH, DEFAULT_EMIT_TIMEOUT_MS, DEFAULT_FILE_READ_TIMEOUT_MS, DEFAULT_LOG_TIMEOUT_MS, DEFAULT_MAX_FILE_BYTES, DEFAULT_MONEY_FIELDS, DEFAULT_WRITE_PREFIXES, type DataClient, type DataIdsOpts, type DataListIdsResult, type DataTransport, type DerivePolicyOptions, type DerivedPolicy, type DispatcherApprovalGate, type DispatcherApprovalOptions, type EmitMarketplaceEventOptions, type EmitResult, type EmitTransport, type EncodeStateWithinEnvelopeOptions, type EncodedStateWithinEnvelope, type EventArgs, type ExecutionContextLike, FILE_REF_SOURCES_HELP, type FetchFileResult, type FetchWithRetryOptions, type FileRef, type FileRefContent, type FileRefEnv, FileRefError, type FileRefErrorCode, type FileRefStream, type FileRefVia, type GetAppFileResult, type HandlerFn, INBOX_SEND_CONTRACT_V1, type IdPrefixSpec, type IdSnapshot, type InboxAddress, type InboxAppendRequest, type InboxAppendResult, type InboxChannelDeclaration, type InboxFoldersRequest, type InboxFoldersResult, type InboxOwner, type InboxSendConnection, type InboxSendHandlerImpl, InboxSendRefusal, type InboxSendSupports, type InboxSendV1Args, type InboxSendV1Result, type InstallBridge, InvalidUndoEnvelopeError, type JournalRowLike, type LogToPlatformOptions, type ManifestDispatchBlock, type ManifestLike, type ManifestToolLike, type MarketplaceEventEmitOpts, type MarketplaceEventSourceIntegration, NotConnectedError, OAUTH_STATE_ENVELOPE_MAX_CHARS, type OAuthBouncerSignals, type OAuthState, type OfferUndoArgs, type PartialUpdateDataOptions, type PlatformHostEnv, type PolicyCheckInput, type PolicySource, type PurgeResult, type PutAppFileArgs, type PutAppFileResult, type PutAppFileStreamArgs, type ReadFileRefOptions, type RequireApprovalOptions, type ResolveFileRefOptions, type ResolveViewerOptions, type ResolvedFileRef, type RestoreResult, type RestoreSpec, SPRIGR_DATA_MAX_OBJECTS_PER_CALL, SPRIGR_FILE_HOSTS, SPRIGR_LOG_LEVELS, SPRIGR_LOG_LIMITS, type ScheduleArgs, type SprigrDataAggregationCell, type SprigrDataAggregationResult, type SprigrDataAggregationSpec, type SprigrDataApi, type SprigrDataImportOpts, type SprigrDataIndexOpts, type SprigrDataPartialUpdateBody, type SprigrDataPartialUpdateOpts, type SprigrDataPartialUpdateResult, type SprigrDataPatch, type SprigrDataSearchOpts, type SprigrDataSearchResult, SprigrDataValidationError, type SprigrFilesApi, type SprigrFilesApiWithEdit, type SprigrFilesCreateInput, type SprigrFilesCreateResult, type SprigrFilesEditInput, type SprigrFilesEditResult, type SprigrFilesJobResult, type SprigrFilesListItem, type SprigrFilesListResult, type SprigrInboxApi, type SprigrLogEntry, type SprigrLogFn, type SprigrLogLevel, type SprigrLogResult, SprigrLogValidationError, type SyncedAttachment, type SyncedMessage, type ToolArgs, type ToolHandler, type ToolResult, type ToolWrapperOptions, UNIT_SEP, type UndoApplyOptions, type UndoApplyResult, type UndoCaptureSpec, type UndoFidelity, VIEWER_ANONYMOUS, VIEWER_CONTEXT_HEADER, VIEWER_PLATFORM_USER_ID_HEADER, VIEWER_ROLE_HEADER, VIEWER_USER_ID_HEADER, type VerbRule, type ViewerContext, type ViewerContextFailure, type ViewerContextVerification, type ViewerEnv, WORKSPACE_FILE_HOW_TO, type WebhookArgs, type WfpBridgeEnv, type WfpEmitReply, actorKey, actorRetiredHook, actorTool, agentFileKeyFromUrl, appFileUrl, appKeyFromCallerKey, applyConfirmationPolicies, approvalHash, approvalPreview, approvalRecipients, archiveOfferRefusal, attendedFindings, base64ToBytes, buildConfirmationPolicy, buildMarketplaceWebhookUrl, buildPartialUpdateBody, bytesToBase64, callerKeyRefusal, canEmit, canLog, canPartialUpdate, checkConfirmationPolicy, commonDestructiveVerbs, connectComplete, connectDisconnect, constantTimeEqual, createMarketplaceEmitter, createToolWrappers, decodeState, defineInboxSendHandler, deleteAppFile, deleteSnapshotIds, deriveConfirmationPolicy, describeMissingBridge, dispatcherApproval, emitMarketplaceEvent, encodeState, encodeStateWithinEnvelope, fetchFileAsBase64, fetchFileBytes, fetchWithRetry, fullWarning, getAppFile, getCompanyTimezone, hmacSha256Hex, installTokenPost, isNotConnectedError, isStagingHost, listAppFiles, logToPlatform, makeDataClient, manifestIsFresh, oauthStateEnvelopeOverhead, offerUndo, openFileRef, overlaySprigr, ownerFromActorKey, parseActor, parseActorRetiredArgs, partialUpdateData, purgeIndexByPrefix, putAppFile, putAppFileStream, randomHex, readFileRef, readableStoredKey, recreatedWarning, refuseWithoutForce, requireApproval, resolveFileRef, resolveInstallBridge, resolveOAuthBouncerBase, resolveOAuthBouncerCallbackUrl, resolvePlatformWebhookBase, resolveViewerContext, resolveViewerUserId, runUndoApply, safeCapture, seq, serializeManifest, set, snapshotIndexIds, tool, undoEnvelope, validateLogEntries, validateLogEntry, verifyViewerToken, withSprigrEmitFallback, withSprigrInboxFallback, withSprigrLogFallback };
|
package/dist/index.js
CHANGED
|
@@ -48,6 +48,36 @@ function decodeState(encoded) {
|
|
|
48
48
|
const json = new TextDecoder().decode(bytes);
|
|
49
49
|
return JSON.parse(json);
|
|
50
50
|
}
|
|
51
|
+
var OAUTH_STATE_ENVELOPE_MAX_CHARS = 500;
|
|
52
|
+
function oauthStateEnvelopeOverhead(installId, appSlug, t = Date.now()) {
|
|
53
|
+
const payloadBytes = new TextEncoder().encode(JSON.stringify({ i: installId, a: appSlug, t })).length;
|
|
54
|
+
const payloadChars = Math.ceil(payloadBytes * 4 / 3);
|
|
55
|
+
return "sps1.".length + 1 + payloadChars + 1 + 22;
|
|
56
|
+
}
|
|
57
|
+
function encodeStateWithinEnvelope(state, opts) {
|
|
58
|
+
const budget = OAUTH_STATE_ENVELOPE_MAX_CHARS - oauthStateEnvelopeOverhead(opts.installId, opts.appSlug);
|
|
59
|
+
const full = encodeState(state);
|
|
60
|
+
if (full.length <= budget) return { state: full, omitted: [], fits: true };
|
|
61
|
+
const trimmed = { ...state };
|
|
62
|
+
const omitted = [];
|
|
63
|
+
for (const key of opts.optional ?? ["returnTo"]) {
|
|
64
|
+
if (!(key in trimmed) || trimmed[key] === void 0) continue;
|
|
65
|
+
const value = trimmed[key];
|
|
66
|
+
delete trimmed[key];
|
|
67
|
+
omitted.push(key);
|
|
68
|
+
const candidate = encodeState(trimmed);
|
|
69
|
+
if (candidate.length <= budget) {
|
|
70
|
+
console.warn(
|
|
71
|
+
`[oauth-state] ${opts.appSlug}: left ${omitted.join(", ")} out of the OAuth state so it can be signed (${String(key)} was ${typeof value === "string" ? value.length : JSON.stringify(value).length} chars; state ${full.length} -> ${candidate.length} chars, room ${budget}). The connect lands on the install's dashboard.`
|
|
72
|
+
);
|
|
73
|
+
return { state: candidate, omitted, fits: true };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
console.warn(
|
|
77
|
+
`[oauth-state] ${opts.appSlug}: the OAuth state is ${full.length} chars and only ${budget} fit inside the signed envelope even without its optional fields, so the platform will send it unsigned.`
|
|
78
|
+
);
|
|
79
|
+
return { state: full, omitted: [], fits: false };
|
|
80
|
+
}
|
|
51
81
|
|
|
52
82
|
// src/fetch.ts
|
|
53
83
|
var DEFAULT_OPTS = {
|
|
@@ -2194,6 +2224,20 @@ async function deleteSnapshotIds(env, snapshot, opts) {
|
|
|
2194
2224
|
async function purgeIndexByPrefix(env, prefixes, opts) {
|
|
2195
2225
|
return deleteSnapshotIds(env, await snapshotIndexIds(env, prefixes), opts);
|
|
2196
2226
|
}
|
|
2227
|
+
|
|
2228
|
+
// src/company.ts
|
|
2229
|
+
function getCompanyTimezone(env) {
|
|
2230
|
+
const raw = env?.COMPANY_TIMEZONE;
|
|
2231
|
+
if (typeof raw !== "string") return void 0;
|
|
2232
|
+
const zone = raw.trim();
|
|
2233
|
+
if (!zone) return void 0;
|
|
2234
|
+
try {
|
|
2235
|
+
new Intl.DateTimeFormat("en-US", { timeZone: zone });
|
|
2236
|
+
return zone;
|
|
2237
|
+
} catch {
|
|
2238
|
+
return void 0;
|
|
2239
|
+
}
|
|
2240
|
+
}
|
|
2197
2241
|
export {
|
|
2198
2242
|
ACTOR_RETIRED_HOOK_TOOL,
|
|
2199
2243
|
ACTOR_RETIRE_REASONS,
|
|
@@ -2215,6 +2259,7 @@ export {
|
|
|
2215
2259
|
InboxSendRefusal,
|
|
2216
2260
|
InvalidUndoEnvelopeError,
|
|
2217
2261
|
NotConnectedError,
|
|
2262
|
+
OAUTH_STATE_ENVELOPE_MAX_CHARS,
|
|
2218
2263
|
SPRIGR_DATA_MAX_OBJECTS_PER_CALL,
|
|
2219
2264
|
SPRIGR_FILE_HOSTS,
|
|
2220
2265
|
SPRIGR_LOG_LEVELS,
|
|
@@ -2265,11 +2310,13 @@ export {
|
|
|
2265
2310
|
dispatcherApproval,
|
|
2266
2311
|
emitMarketplaceEvent,
|
|
2267
2312
|
encodeState,
|
|
2313
|
+
encodeStateWithinEnvelope,
|
|
2268
2314
|
fetchFileAsBase64,
|
|
2269
2315
|
fetchFileBytes,
|
|
2270
2316
|
fetchWithRetry,
|
|
2271
2317
|
fullWarning,
|
|
2272
2318
|
getAppFile,
|
|
2319
|
+
getCompanyTimezone,
|
|
2273
2320
|
hmacSha256Hex,
|
|
2274
2321
|
installTokenPost,
|
|
2275
2322
|
isNotConnectedError,
|
|
@@ -2278,6 +2325,7 @@ export {
|
|
|
2278
2325
|
logToPlatform,
|
|
2279
2326
|
makeDataClient,
|
|
2280
2327
|
manifestIsFresh,
|
|
2328
|
+
oauthStateEnvelopeOverhead,
|
|
2281
2329
|
offerUndo,
|
|
2282
2330
|
openFileRef,
|
|
2283
2331
|
overlaySprigr,
|