@nlabs/reaktor 1.16.0 → 1.18.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 +186 -0
- package/docs/ASSISTANT.md +138 -0
- package/docs/GENERATION.md +29 -2
- package/docs/NATIVE_PUSH.md +56 -0
- package/lib/actions/alfredFaq.d.ts +80 -0
- package/lib/actions/alfredFaq.js +206 -0
- package/lib/actions/contentGeneration.d.ts +4 -1
- package/lib/actions/contentGeneration.js +83 -27
- package/lib/actions/contentGenerationErrors.js +1 -1
- package/lib/actions/conversations.d.ts +1 -1
- package/lib/actions/conversations.js +19 -9
- package/lib/actions/crud.js +26 -1
- package/lib/actions/index.d.ts +2 -0
- package/lib/actions/index.js +3 -1
- package/lib/actions/messages.js +23 -7
- package/lib/actions/phoneSupport.d.ts +18 -0
- package/lib/actions/phoneSupport.js +170 -0
- package/lib/actions/users.js +57 -4
- package/lib/assistant/core.d.ts +53 -0
- package/lib/assistant/core.js +123 -0
- package/lib/assistant/faq.d.ts +26 -0
- package/lib/assistant/faq.js +238 -0
- package/lib/assistant/faqCore.d.ts +23 -0
- package/lib/assistant/faqCore.js +20 -0
- package/lib/assistant/index.d.ts +7 -0
- package/lib/assistant/index.js +5 -0
- package/lib/assistant/service.d.ts +35 -0
- package/lib/assistant/service.js +201 -0
- package/lib/config.js +3 -2
- package/lib/durableChat/conversations.d.ts +62 -0
- package/lib/durableChat/conversations.js +729 -0
- package/lib/durableChat/errors.d.ts +6 -0
- package/lib/durableChat/errors.js +11 -0
- package/lib/durableChat/events.d.ts +22 -0
- package/lib/durableChat/events.js +50 -0
- package/lib/durableChat/index.d.ts +8 -0
- package/lib/durableChat/index.js +10 -0
- package/lib/durableChat/membership.d.ts +24 -0
- package/lib/durableChat/membership.js +85 -0
- package/lib/durableChat/messageTypes.d.ts +76 -0
- package/lib/durableChat/messageTypes.js +3 -0
- package/lib/durableChat/messages.d.ts +16 -0
- package/lib/durableChat/messages.js +257 -0
- package/lib/durableChat/transaction.d.ts +10 -0
- package/lib/durableChat/transaction.js +53 -0
- package/lib/durableChat/types.d.ts +81 -0
- package/lib/durableChat/types.js +3 -0
- package/lib/index.d.ts +4 -4
- package/lib/index.js +5 -3
- package/lib/lambdas/actions/websockets.js +4 -4
- package/lib/nativePush/graphql.d.ts +14 -0
- package/lib/nativePush/graphql.js +105 -0
- package/lib/nativePush/index.d.ts +7 -0
- package/lib/nativePush/index.js +9 -0
- package/lib/nativePush/migrations.d.ts +2 -0
- package/lib/nativePush/migrations.js +36 -0
- package/lib/nativePush/nativePushContract.fixture.d.ts +22 -0
- package/lib/nativePush/nativePushContract.fixture.js +27 -0
- package/lib/nativePush/payload.d.ts +2 -0
- package/lib/nativePush/payload.js +106 -0
- package/lib/nativePush/repository.d.ts +9 -0
- package/lib/nativePush/repository.js +120 -0
- package/lib/nativePush/service.d.ts +2 -0
- package/lib/nativePush/service.js +110 -0
- package/lib/nativePush/snsProvider.d.ts +17 -0
- package/lib/nativePush/snsProvider.js +165 -0
- package/lib/nativePush/types.d.ts +89 -0
- package/lib/nativePush/types.js +3 -0
- package/lib/organizations/accountLifecycle.d.ts +7 -0
- package/lib/organizations/accountLifecycle.js +106 -0
- package/lib/organizations/authorization.d.ts +9 -0
- package/lib/organizations/authorization.js +40 -0
- package/lib/organizations/billing.d.ts +38 -0
- package/lib/organizations/billing.js +277 -0
- package/lib/organizations/billingProvider.d.ts +4 -0
- package/lib/organizations/billingProvider.js +287 -0
- package/lib/organizations/billingUpdates.d.ts +9 -0
- package/lib/organizations/billingUpdates.js +388 -0
- package/lib/organizations/index.d.ts +10 -0
- package/lib/organizations/index.js +12 -0
- package/lib/organizations/mail.d.ts +10 -0
- package/lib/organizations/mail.js +60 -0
- package/lib/organizations/memberDirectory.d.ts +15 -0
- package/lib/organizations/memberDirectory.js +28 -0
- package/lib/organizations/membership.d.ts +19 -0
- package/lib/organizations/membership.js +248 -0
- package/lib/organizations/passwordRecovery.d.ts +9 -0
- package/lib/organizations/passwordRecovery.js +50 -0
- package/lib/organizations/plans.d.ts +6 -0
- package/lib/organizations/plans.js +40 -0
- package/lib/organizations/providerPagination.d.ts +6 -0
- package/lib/organizations/providerPagination.js +23 -0
- package/lib/organizations/reconciliation.d.ts +11 -0
- package/lib/organizations/reconciliation.js +400 -0
- package/lib/organizations/signup.d.ts +25 -0
- package/lib/organizations/signup.js +169 -0
- package/lib/organizations/store.d.ts +25 -0
- package/lib/organizations/store.js +167 -0
- package/lib/organizations/types.d.ts +138 -0
- package/lib/organizations/types.js +3 -0
- package/lib/organizations/verification.d.ts +3 -0
- package/lib/organizations/verification.js +51 -0
- package/package.json +16 -3
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { buildNativePushPayload } from './payload.js';
|
|
3
|
+
import { createSnsPushProvider, NativePushProviderError } from './snsProvider.js';
|
|
4
|
+
const validId = (value)=>typeof value === 'string' && value.length > 0 && value.length <= 256;
|
|
5
|
+
const checkActor = (actor)=>{
|
|
6
|
+
if (!validId(actor?.userId) || !validId(actor?.sessionId)) {
|
|
7
|
+
throw new Error('Authenticated push session required');
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
export const createNativePushService = (options)=>{
|
|
11
|
+
const { canDeliver, isSessionEligible, repository, scope } = options;
|
|
12
|
+
if (!validId(scope?.appId) || !validId(scope?.environment)) {
|
|
13
|
+
throw new Error('Invalid push scope');
|
|
14
|
+
}
|
|
15
|
+
const provider = createSnsPushProvider(options);
|
|
16
|
+
const now = options.now ?? (()=>new Date());
|
|
17
|
+
const sessionRequired = async (actor)=>{
|
|
18
|
+
checkActor(actor);
|
|
19
|
+
if (!await isSessionEligible(scope, actor)) {
|
|
20
|
+
throw new Error('Active push session required');
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
return {
|
|
24
|
+
register: async (actor, input)=>{
|
|
25
|
+
await sessionRequired(actor);
|
|
26
|
+
if (!validId(input?.installationId) || !validId(input?.platform) || typeof input.token !== 'string' || !input.token || input.token.length > 8192) {
|
|
27
|
+
throw new Error('Invalid push registration');
|
|
28
|
+
}
|
|
29
|
+
const { token } = input;
|
|
30
|
+
const safeInput = {
|
|
31
|
+
...input.platform === 'IOS' && {
|
|
32
|
+
apnsEnvironment: input.apnsEnvironment
|
|
33
|
+
},
|
|
34
|
+
installationId: input.installationId,
|
|
35
|
+
platform: input.platform
|
|
36
|
+
};
|
|
37
|
+
const tokenHash = createHash('sha256').update(token).digest('hex');
|
|
38
|
+
const revision = await repository.reserveBinding(scope, actor, safeInput, tokenHash);
|
|
39
|
+
// Create/reconcile by token, never retarget an installation's previous endpoint.
|
|
40
|
+
// A delayed old operation must not change the token on a newer SNS binding.
|
|
41
|
+
const arn = await provider.ensureEndpoint(input);
|
|
42
|
+
await sessionRequired(actor);
|
|
43
|
+
const registration = await repository.replaceBinding(scope, actor, safeInput, arn, tokenHash, revision);
|
|
44
|
+
try {
|
|
45
|
+
await sessionRequired(actor);
|
|
46
|
+
return registration;
|
|
47
|
+
} catch (error) {
|
|
48
|
+
await repository.disableBinding(scope, actor, registration.registrationId, registration.revision);
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
send: async (userId, notification, pushOptions = {})=>{
|
|
53
|
+
if (!validId(userId)) {
|
|
54
|
+
throw new Error('Invalid push recipient');
|
|
55
|
+
}
|
|
56
|
+
const results = [];
|
|
57
|
+
const records = await repository.listEnabled(scope, userId);
|
|
58
|
+
// Sequential dispatch bounds provider load and keeps eligibility checks near each publish.
|
|
59
|
+
/* eslint-disable no-await-in-loop */ for (const registration of records){
|
|
60
|
+
const result = {
|
|
61
|
+
registrationId: registration.registrationId,
|
|
62
|
+
status: 'SKIPPED'
|
|
63
|
+
};
|
|
64
|
+
results.push(result);
|
|
65
|
+
if (!registration.enabled || registration.appId !== scope.appId || registration.environment !== scope.environment || registration.userId !== userId) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
if (canDeliver && !await canDeliver(registration, notification)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (!await isSessionEligible(scope, registration) || !await repository.isCurrent(registration)) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const payload = buildNativePushPayload(registration.platform, registration.apnsEnvironment, {
|
|
76
|
+
notification,
|
|
77
|
+
recipientUserId: userId,
|
|
78
|
+
scope
|
|
79
|
+
}, pushOptions, now());
|
|
80
|
+
const response = await provider.publish(registration.endpointArn, payload);
|
|
81
|
+
result.status = 'ACCEPTED';
|
|
82
|
+
result.providerMessageId = response.messageId;
|
|
83
|
+
} catch (error) {
|
|
84
|
+
const code = error instanceof NativePushProviderError ? error.code : 'DeliveryFailed';
|
|
85
|
+
result.code = code;
|
|
86
|
+
if ([
|
|
87
|
+
'EndpointDisabledException',
|
|
88
|
+
'NotFoundException'
|
|
89
|
+
].includes(code)) {
|
|
90
|
+
result.status = 'INVALID_ENDPOINT';
|
|
91
|
+
await repository.disableBinding(scope, registration, registration.registrationId, registration.revision);
|
|
92
|
+
} else {
|
|
93
|
+
result.status = error instanceof NativePushProviderError && error.transient ? 'TRANSIENT_FAILURE' : 'PERMANENT_FAILURE';
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/* eslint-enable no-await-in-loop */ return results;
|
|
98
|
+
},
|
|
99
|
+
unregister: async (actor, registrationId, revision)=>{
|
|
100
|
+
checkActor(actor);
|
|
101
|
+
if (!validId(registrationId) || revision !== undefined && (!Number.isInteger(revision) || revision < 1)) {
|
|
102
|
+
throw new Error('Invalid push registration identity');
|
|
103
|
+
}
|
|
104
|
+
// Local binding only: shared SNS endpoints must not be disabled by logout.
|
|
105
|
+
return repository.disableBinding(scope, actor, registrationId, revision);
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3IvcGFja2FnZXMvcmVha3Rvci9zcmMvbmF0aXZlUHVzaC9zZXJ2aWNlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Y3JlYXRlSGFzaH0gZnJvbSAnbm9kZTpjcnlwdG8nO1xuXG5pbXBvcnQge2J1aWxkTmF0aXZlUHVzaFBheWxvYWR9IGZyb20gJy4vcGF5bG9hZC5qcyc7XG5pbXBvcnQge2NyZWF0ZVNuc1B1c2hQcm92aWRlciwgTmF0aXZlUHVzaFByb3ZpZGVyRXJyb3J9IGZyb20gJy4vc25zUHJvdmlkZXIuanMnO1xuXG5pbXBvcnQgdHlwZSB7RGVsaXZlcnlPdXRjb21lLCBOYXRpdmVQdXNoU2VydmljZSwgTmF0aXZlUHVzaFNlcnZpY2VPcHRpb25zLCBQdXNoQWN0b3J9IGZyb20gJy4vdHlwZXMuanMnO1xuXG5jb25zdCB2YWxpZElkID0gKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgc3RyaW5nID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycgJiYgdmFsdWUubGVuZ3RoID4gMCAmJiB2YWx1ZS5sZW5ndGggPD0gMjU2O1xuY29uc3QgY2hlY2tBY3RvciA9IChhY3RvcjogUHVzaEFjdG9yKTogdm9pZCA9PiB7XG4gIGlmKCF2YWxpZElkKGFjdG9yPy51c2VySWQpIHx8ICF2YWxpZElkKGFjdG9yPy5zZXNzaW9uSWQpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdBdXRoZW50aWNhdGVkIHB1c2ggc2Vzc2lvbiByZXF1aXJlZCcpO1xuICB9XG59O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlTmF0aXZlUHVzaFNlcnZpY2UgPSAob3B0aW9uczogTmF0aXZlUHVzaFNlcnZpY2VPcHRpb25zKTogTmF0aXZlUHVzaFNlcnZpY2UgPT4ge1xuICBjb25zdCB7Y2FuRGVsaXZlciwgaXNTZXNzaW9uRWxpZ2libGUsIHJlcG9zaXRvcnksIHNjb3BlfSA9IG9wdGlvbnM7XG4gIGlmKCF2YWxpZElkKHNjb3BlPy5hcHBJZCkgfHwgIXZhbGlkSWQoc2NvcGU/LmVudmlyb25tZW50KSkge1xuICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBwdXNoIHNjb3BlJyk7XG4gIH1cbiAgY29uc3QgcHJvdmlkZXIgPSBjcmVhdGVTbnNQdXNoUHJvdmlkZXIob3B0aW9ucyk7XG4gIGNvbnN0IG5vdyA9IG9wdGlvbnMubm93ID8/ICgoKSA9PiBuZXcgRGF0ZSgpKTtcbiAgY29uc3Qgc2Vzc2lvblJlcXVpcmVkID0gYXN5bmMgKGFjdG9yOiBQdXNoQWN0b3IpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICBjaGVja0FjdG9yKGFjdG9yKTtcbiAgICBpZighYXdhaXQgaXNTZXNzaW9uRWxpZ2libGUoc2NvcGUsIGFjdG9yKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBY3RpdmUgcHVzaCBzZXNzaW9uIHJlcXVpcmVkJyk7XG4gICAgfVxuICB9O1xuICByZXR1cm4ge1xuICAgIHJlZ2lzdGVyOiBhc3luYyAoYWN0b3IsIGlucHV0KSA9PiB7XG4gICAgICBhd2FpdCBzZXNzaW9uUmVxdWlyZWQoYWN0b3IpO1xuICAgICAgaWYoIXZhbGlkSWQoaW5wdXQ/Lmluc3RhbGxhdGlvbklkKSB8fCAhdmFsaWRJZChpbnB1dD8ucGxhdGZvcm0pIHx8XG4gICAgICAgIHR5cGVvZiBpbnB1dC50b2tlbiAhPT0gJ3N0cmluZycgfHwgIWlucHV0LnRva2VuIHx8IGlucHV0LnRva2VuLmxlbmd0aCA+IDgxOTIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHB1c2ggcmVnaXN0cmF0aW9uJyk7XG4gICAgICB9XG4gICAgICBjb25zdCB7dG9rZW59ID0gaW5wdXQ7XG4gICAgICBjb25zdCBzYWZlSW5wdXQgPSB7XG4gICAgICAgIC4uLihpbnB1dC5wbGF0Zm9ybSA9PT0gJ0lPUycgJiYge2FwbnNFbnZpcm9ubWVudDogaW5wdXQuYXBuc0Vudmlyb25tZW50fSksXG4gICAgICAgIGluc3RhbGxhdGlvbklkOiBpbnB1dC5pbnN0YWxsYXRpb25JZCxcbiAgICAgICAgcGxhdGZvcm06IGlucHV0LnBsYXRmb3JtXG4gICAgICB9O1xuICAgICAgY29uc3QgdG9rZW5IYXNoID0gY3JlYXRlSGFzaCgnc2hhMjU2JykudXBkYXRlKHRva2VuKS5kaWdlc3QoJ2hleCcpO1xuICAgICAgY29uc3QgcmV2aXNpb24gPSBhd2FpdCByZXBvc2l0b3J5LnJlc2VydmVCaW5kaW5nKHNjb3BlLCBhY3Rvciwgc2FmZUlucHV0LCB0b2tlbkhhc2gpO1xuICAgICAgLy8gQ3JlYXRlL3JlY29uY2lsZSBieSB0b2tlbiwgbmV2ZXIgcmV0YXJnZXQgYW4gaW5zdGFsbGF0aW9uJ3MgcHJldmlvdXMgZW5kcG9pbnQuXG4gICAgICAvLyBBIGRlbGF5ZWQgb2xkIG9wZXJhdGlvbiBtdXN0IG5vdCBjaGFuZ2UgdGhlIHRva2VuIG9uIGEgbmV3ZXIgU05TIGJpbmRpbmcuXG4gICAgICBjb25zdCBhcm4gPSBhd2FpdCBwcm92aWRlci5lbnN1cmVFbmRwb2ludChpbnB1dCk7XG4gICAgICBhd2FpdCBzZXNzaW9uUmVxdWlyZWQoYWN0b3IpO1xuICAgICAgY29uc3QgcmVnaXN0cmF0aW9uID0gYXdhaXQgcmVwb3NpdG9yeS5yZXBsYWNlQmluZGluZyhzY29wZSwgYWN0b3IsIHNhZmVJbnB1dCwgYXJuLFxuICAgICAgICB0b2tlbkhhc2gsIHJldmlzaW9uKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHNlc3Npb25SZXF1aXJlZChhY3Rvcik7XG4gICAgICAgIHJldHVybiByZWdpc3RyYXRpb247XG4gICAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICAgIGF3YWl0IHJlcG9zaXRvcnkuZGlzYWJsZUJpbmRpbmcoc2NvcGUsIGFjdG9yLCByZWdpc3RyYXRpb24ucmVnaXN0cmF0aW9uSWQsIHJlZ2lzdHJhdGlvbi5yZXZpc2lvbik7XG4gICAgICAgIHRocm93IGVycm9yO1xuICAgICAgfVxuICAgIH0sXG4gICAgc2VuZDogYXN5bmMgKHVzZXJJZCwgbm90aWZpY2F0aW9uLCBwdXNoT3B0aW9ucyA9IHt9KSA9PiB7XG4gICAgICBpZighdmFsaWRJZCh1c2VySWQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBwdXNoIHJlY2lwaWVudCcpO1xuICAgICAgfVxuICAgICAgY29uc3QgcmVzdWx0czogRGVsaXZlcnlPdXRjb21lW10gPSBbXTtcbiAgICAgIGNvbnN0IHJlY29yZHMgPSBhd2FpdCByZXBvc2l0b3J5Lmxpc3RFbmFibGVkKHNjb3BlLCB1c2VySWQpO1xuICAgICAgLy8gU2VxdWVudGlhbCBkaXNwYXRjaCBib3VuZHMgcHJvdmlkZXIgbG9hZCBhbmQga2VlcHMgZWxpZ2liaWxpdHkgY2hlY2tzIG5lYXIgZWFjaCBwdWJsaXNoLlxuICAgICAgLyogZXNsaW50LWRpc2FibGUgbm8tYXdhaXQtaW4tbG9vcCAqL1xuICAgICAgZm9yKGNvbnN0IHJlZ2lzdHJhdGlvbiBvZiByZWNvcmRzKSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdDogRGVsaXZlcnlPdXRjb21lID0ge3JlZ2lzdHJhdGlvbklkOiByZWdpc3RyYXRpb24ucmVnaXN0cmF0aW9uSWQsIHN0YXR1czogJ1NLSVBQRUQnfTtcbiAgICAgICAgcmVzdWx0cy5wdXNoKHJlc3VsdCk7XG4gICAgICAgIGlmKCFyZWdpc3RyYXRpb24uZW5hYmxlZCB8fCByZWdpc3RyYXRpb24uYXBwSWQgIT09IHNjb3BlLmFwcElkIHx8XG4gICAgICAgICAgcmVnaXN0cmF0aW9uLmVudmlyb25tZW50ICE9PSBzY29wZS5lbnZpcm9ubWVudCB8fCByZWdpc3RyYXRpb24udXNlcklkICE9PSB1c2VySWQpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGlmKGNhbkRlbGl2ZXIgJiYgIWF3YWl0IGNhbkRlbGl2ZXIocmVnaXN0cmF0aW9uLCBub3RpZmljYXRpb24pKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYoIWF3YWl0IGlzU2Vzc2lvbkVsaWdpYmxlKHNjb3BlLCByZWdpc3RyYXRpb24pIHx8ICFhd2FpdCByZXBvc2l0b3J5LmlzQ3VycmVudChyZWdpc3RyYXRpb24pKSB7XG4gICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICB9XG4gICAgICAgICAgY29uc3QgcGF5bG9hZCA9IGJ1aWxkTmF0aXZlUHVzaFBheWxvYWQocmVnaXN0cmF0aW9uLnBsYXRmb3JtLCByZWdpc3RyYXRpb24uYXBuc0Vudmlyb25tZW50LFxuICAgICAgICAgICAge25vdGlmaWNhdGlvbiwgcmVjaXBpZW50VXNlcklkOiB1c2VySWQsIHNjb3BlfSwgcHVzaE9wdGlvbnMsIG5vdygpKTtcbiAgICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHByb3ZpZGVyLnB1Ymxpc2gocmVnaXN0cmF0aW9uLmVuZHBvaW50QXJuLCBwYXlsb2FkKTtcbiAgICAgICAgICByZXN1bHQuc3RhdHVzID0gJ0FDQ0VQVEVEJztcbiAgICAgICAgICByZXN1bHQucHJvdmlkZXJNZXNzYWdlSWQgPSByZXNwb25zZS5tZXNzYWdlSWQ7XG4gICAgICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgICAgICBjb25zdCBjb2RlID0gZXJyb3IgaW5zdGFuY2VvZiBOYXRpdmVQdXNoUHJvdmlkZXJFcnJvciA/IGVycm9yLmNvZGUgOiAnRGVsaXZlcnlGYWlsZWQnO1xuICAgICAgICAgIHJlc3VsdC5jb2RlID0gY29kZTtcbiAgICAgICAgICBpZihbJ0VuZHBvaW50RGlzYWJsZWRFeGNlcHRpb24nLCAnTm90Rm91bmRFeGNlcHRpb24nXS5pbmNsdWRlcyhjb2RlKSkge1xuICAgICAgICAgICAgcmVzdWx0LnN0YXR1cyA9ICdJTlZBTElEX0VORFBPSU5UJztcbiAgICAgICAgICAgIGF3YWl0IHJlcG9zaXRvcnkuZGlzYWJsZUJpbmRpbmcoc2NvcGUsIHJlZ2lzdHJhdGlvbiwgcmVnaXN0cmF0aW9uLnJlZ2lzdHJhdGlvbklkLCByZWdpc3RyYXRpb24ucmV2aXNpb24pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXN1bHQuc3RhdHVzID0gZXJyb3IgaW5zdGFuY2VvZiBOYXRpdmVQdXNoUHJvdmlkZXJFcnJvciAmJiBlcnJvci50cmFuc2llbnRcbiAgICAgICAgICAgICAgPyAnVFJBTlNJRU5UX0ZBSUxVUkUnIDogJ1BFUk1BTkVOVF9GQUlMVVJFJztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8qIGVzbGludC1lbmFibGUgbm8tYXdhaXQtaW4tbG9vcCAqL1xuICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgfSxcbiAgICB1bnJlZ2lzdGVyOiBhc3luYyAoYWN0b3IsIHJlZ2lzdHJhdGlvbklkLCByZXZpc2lvbikgPT4ge1xuICAgICAgY2hlY2tBY3RvcihhY3Rvcik7XG4gICAgICBpZighdmFsaWRJZChyZWdpc3RyYXRpb25JZCkgfHwgKHJldmlzaW9uICE9PSB1bmRlZmluZWQgJiYgKCFOdW1iZXIuaXNJbnRlZ2VyKHJldmlzaW9uKSB8fCByZXZpc2lvbiA8IDEpKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0ludmFsaWQgcHVzaCByZWdpc3RyYXRpb24gaWRlbnRpdHknKTtcbiAgICAgIH1cbiAgICAgIC8vIExvY2FsIGJpbmRpbmcgb25seTogc2hhcmVkIFNOUyBlbmRwb2ludHMgbXVzdCBub3QgYmUgZGlzYWJsZWQgYnkgbG9nb3V0LlxuICAgICAgcmV0dXJuIHJlcG9zaXRvcnkuZGlzYWJsZUJpbmRpbmcoc2NvcGUsIGFjdG9yLCByZWdpc3RyYXRpb25JZCwgcmV2aXNpb24pO1xuICAgIH1cbiAgfTtcbn07XG4iXSwibmFtZXMiOlsiY3JlYXRlSGFzaCIsImJ1aWxkTmF0aXZlUHVzaFBheWxvYWQiLCJjcmVhdGVTbnNQdXNoUHJvdmlkZXIiLCJOYXRpdmVQdXNoUHJvdmlkZXJFcnJvciIsInZhbGlkSWQiLCJ2YWx1ZSIsImxlbmd0aCIsImNoZWNrQWN0b3IiLCJhY3RvciIsInVzZXJJZCIsInNlc3Npb25JZCIsIkVycm9yIiwiY3JlYXRlTmF0aXZlUHVzaFNlcnZpY2UiLCJvcHRpb25zIiwiY2FuRGVsaXZlciIsImlzU2Vzc2lvbkVsaWdpYmxlIiwicmVwb3NpdG9yeSIsInNjb3BlIiwiYXBwSWQiLCJlbnZpcm9ubWVudCIsInByb3ZpZGVyIiwibm93IiwiRGF0ZSIsInNlc3Npb25SZXF1aXJlZCIsInJlZ2lzdGVyIiwiaW5wdXQiLCJpbnN0YWxsYXRpb25JZCIsInBsYXRmb3JtIiwidG9rZW4iLCJzYWZlSW5wdXQiLCJhcG5zRW52aXJvbm1lbnQiLCJ0b2tlbkhhc2giLCJ1cGRhdGUiLCJkaWdlc3QiLCJyZXZpc2lvbiIsInJlc2VydmVCaW5kaW5nIiwiYXJuIiwiZW5zdXJlRW5kcG9pbnQiLCJyZWdpc3RyYXRpb24iLCJyZXBsYWNlQmluZGluZyIsImVycm9yIiwiZGlzYWJsZUJpbmRpbmciLCJyZWdpc3RyYXRpb25JZCIsInNlbmQiLCJub3RpZmljYXRpb24iLCJwdXNoT3B0aW9ucyIsInJlc3VsdHMiLCJyZWNvcmRzIiwibGlzdEVuYWJsZWQiLCJyZXN1bHQiLCJzdGF0dXMiLCJwdXNoIiwiZW5hYmxlZCIsImlzQ3VycmVudCIsInBheWxvYWQiLCJyZWNpcGllbnRVc2VySWQiLCJyZXNwb25zZSIsInB1Ymxpc2giLCJlbmRwb2ludEFybiIsInByb3ZpZGVyTWVzc2FnZUlkIiwibWVzc2FnZUlkIiwiY29kZSIsImluY2x1ZGVzIiwidHJhbnNpZW50IiwidW5yZWdpc3RlciIsInVuZGVmaW5lZCIsIk51bWJlciIsImlzSW50ZWdlciJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBUUEsVUFBVSxRQUFPLGNBQWM7QUFFdkMsU0FBUUMsc0JBQXNCLFFBQU8sZUFBZTtBQUNwRCxTQUFRQyxxQkFBcUIsRUFBRUMsdUJBQXVCLFFBQU8sbUJBQW1CO0FBSWhGLE1BQU1DLFVBQVUsQ0FBQ0MsUUFBb0MsT0FBT0EsVUFBVSxZQUFZQSxNQUFNQyxNQUFNLEdBQUcsS0FBS0QsTUFB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
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { NativePushPayload, NativePushRegistrationInput, PlatformApplicationArns, SnsSender } from './types.js';
|
|
2
|
+
export declare class NativePushProviderError extends Error {
|
|
3
|
+
readonly code: string;
|
|
4
|
+
readonly transient: boolean;
|
|
5
|
+
constructor(code: string, transient?: boolean);
|
|
6
|
+
}
|
|
7
|
+
export declare const createSnsPushProvider: ({ sns, platformApplicationArns, delay }: {
|
|
8
|
+
delay?: (milliseconds: number) => Promise<void>;
|
|
9
|
+
platformApplicationArns: PlatformApplicationArns;
|
|
10
|
+
sns: SnsSender;
|
|
11
|
+
}) => {
|
|
12
|
+
disableEndpoint: (endpointArn: string) => Promise<void>;
|
|
13
|
+
ensureEndpoint: (input: NativePushRegistrationInput, existingEndpointArn?: string) => Promise<string>;
|
|
14
|
+
publish: (endpointArn: string, payload: NativePushPayload) => Promise<{
|
|
15
|
+
messageId: string;
|
|
16
|
+
}>;
|
|
17
|
+
};
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import { CreatePlatformEndpointCommand, GetEndpointAttributesCommand, PublishCommand, SetEndpointAttributesCommand } from '@aws-sdk/client-sns';
|
|
2
|
+
export class NativePushProviderError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
transient;
|
|
5
|
+
constructor(code, transient = false){
|
|
6
|
+
super(`Native push provider error: ${code}`);
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.name = 'NativePushProviderError';
|
|
9
|
+
this.transient = transient;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const errorCode = (error)=>{
|
|
13
|
+
const name = error?.name;
|
|
14
|
+
return typeof name === 'string' && /^[A-Za-z]{1,80}$/.test(name) ? name : 'UnknownProviderError';
|
|
15
|
+
};
|
|
16
|
+
const transientCodes = new Set([
|
|
17
|
+
'ThrottledException',
|
|
18
|
+
'ThrottlingException',
|
|
19
|
+
'InternalErrorException',
|
|
20
|
+
'ServiceUnavailableException',
|
|
21
|
+
'TimeoutError',
|
|
22
|
+
'NetworkingError'
|
|
23
|
+
]);
|
|
24
|
+
export const createSnsPushProvider = ({ sns, platformApplicationArns, delay = (ms)=>new Promise((resolve)=>setTimeout(resolve, ms)) })=>{
|
|
25
|
+
const applicationFor = (input)=>{
|
|
26
|
+
let arn;
|
|
27
|
+
let expected;
|
|
28
|
+
if (input.platform === 'ANDROID') {
|
|
29
|
+
arn = platformApplicationArns.android;
|
|
30
|
+
expected = 'GCM';
|
|
31
|
+
} else if (input.platform === 'IOS' && input.apnsEnvironment === 'sandbox') {
|
|
32
|
+
arn = platformApplicationArns.iosSandbox;
|
|
33
|
+
expected = 'APNS_SANDBOX';
|
|
34
|
+
} else if (input.platform === 'IOS' && input.apnsEnvironment === 'production') {
|
|
35
|
+
arn = platformApplicationArns.iosProduction;
|
|
36
|
+
expected = 'APNS';
|
|
37
|
+
}
|
|
38
|
+
if (!arn || !new RegExp(`^arn:[a-z0-9-]+:sns:[a-z0-9-]+:[0-9]{12}:app/${expected}/[A-Za-z0-9_.-]+$`).test(arn)) {
|
|
39
|
+
throw new NativePushProviderError('InvalidApplicationConfiguration');
|
|
40
|
+
}
|
|
41
|
+
return arn;
|
|
42
|
+
};
|
|
43
|
+
const endpointMatches = (arn, application)=>{
|
|
44
|
+
const prefix = `${application.replace(':app/', ':endpoint/')}/`;
|
|
45
|
+
return arn.startsWith(prefix) && /^[A-Za-z0-9-]+$/.test(arn.slice(prefix.length));
|
|
46
|
+
};
|
|
47
|
+
const endpointAllowed = (arn)=>Object.values(platformApplicationArns).some((application)=>application && endpointMatches(arn, application));
|
|
48
|
+
const call = async (command)=>{
|
|
49
|
+
for(let attempt = 0;; attempt++){
|
|
50
|
+
try {
|
|
51
|
+
// Sequential retries deliberately wait for the preceding attempt.
|
|
52
|
+
// eslint-disable-next-line no-await-in-loop
|
|
53
|
+
return await sns.send(command);
|
|
54
|
+
} catch (error) {
|
|
55
|
+
const code = errorCode(error);
|
|
56
|
+
if (transientCodes.has(code) && attempt < 2) {
|
|
57
|
+
// eslint-disable-next-line no-await-in-loop
|
|
58
|
+
await delay(100 * 2 ** attempt);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
throw new NativePushProviderError(code, transientCodes.has(code));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
const ensureEndpoint = async (input, existingEndpointArn)=>{
|
|
66
|
+
const application = applicationFor(input);
|
|
67
|
+
if (!input.token || typeof input.token !== 'string' || input.token.length > 8192) {
|
|
68
|
+
throw new NativePushProviderError('InvalidDeviceToken');
|
|
69
|
+
}
|
|
70
|
+
if (existingEndpointArn && !endpointMatches(existingEndpointArn, application)) {
|
|
71
|
+
throw new NativePushProviderError('InvalidEndpointScope');
|
|
72
|
+
}
|
|
73
|
+
const create = async ()=>{
|
|
74
|
+
let arn;
|
|
75
|
+
for(let attempt = 0;; attempt++){
|
|
76
|
+
try {
|
|
77
|
+
// Keep the AWS duplicate-endpoint diagnostic local; never expose it or its token.
|
|
78
|
+
// eslint-disable-next-line no-await-in-loop
|
|
79
|
+
const result = await sns.send(new CreatePlatformEndpointCommand({
|
|
80
|
+
PlatformApplicationArn: application,
|
|
81
|
+
Token: input.token
|
|
82
|
+
}));
|
|
83
|
+
arn = result.EndpointArn;
|
|
84
|
+
break;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
if (errorCode(error) === 'InvalidParameterException') {
|
|
87
|
+
const diagnostic = error.message ?? '';
|
|
88
|
+
arn = diagnostic.match(/Endpoint (arn:[^\s]+) already exists with the same Token/)?.[1];
|
|
89
|
+
}
|
|
90
|
+
if (arn) {
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
if (transientCodes.has(errorCode(error)) && attempt < 2) {
|
|
94
|
+
// eslint-disable-next-line no-await-in-loop
|
|
95
|
+
await delay(100 * 2 ** attempt);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
throw new NativePushProviderError(errorCode(error), transientCodes.has(errorCode(error)));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (!arn || !endpointMatches(arn, application)) {
|
|
102
|
+
throw new NativePushProviderError('InvalidEndpointScope');
|
|
103
|
+
}
|
|
104
|
+
return arn;
|
|
105
|
+
};
|
|
106
|
+
let arn = existingEndpointArn ?? await create();
|
|
107
|
+
let result;
|
|
108
|
+
try {
|
|
109
|
+
result = await call(new GetEndpointAttributesCommand({
|
|
110
|
+
EndpointArn: arn
|
|
111
|
+
}));
|
|
112
|
+
} catch (error) {
|
|
113
|
+
if (error.code !== 'NotFoundException') {
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
116
|
+
arn = await create();
|
|
117
|
+
result = await call(new GetEndpointAttributesCommand({
|
|
118
|
+
EndpointArn: arn
|
|
119
|
+
}));
|
|
120
|
+
}
|
|
121
|
+
if (result.Attributes?.Token !== input.token || result.Attributes?.Enabled !== 'true') {
|
|
122
|
+
await call(new SetEndpointAttributesCommand({
|
|
123
|
+
Attributes: {
|
|
124
|
+
Enabled: 'true',
|
|
125
|
+
Token: input.token
|
|
126
|
+
},
|
|
127
|
+
EndpointArn: arn
|
|
128
|
+
}));
|
|
129
|
+
}
|
|
130
|
+
return arn;
|
|
131
|
+
};
|
|
132
|
+
return {
|
|
133
|
+
disableEndpoint: async (endpointArn)=>{
|
|
134
|
+
if (!endpointAllowed(endpointArn)) {
|
|
135
|
+
throw new NativePushProviderError('InvalidEndpointScope');
|
|
136
|
+
}
|
|
137
|
+
await call(new SetEndpointAttributesCommand({
|
|
138
|
+
Attributes: {
|
|
139
|
+
Enabled: 'false'
|
|
140
|
+
},
|
|
141
|
+
EndpointArn: endpointArn
|
|
142
|
+
}));
|
|
143
|
+
},
|
|
144
|
+
ensureEndpoint,
|
|
145
|
+
publish: async (endpointArn, payload)=>{
|
|
146
|
+
if (!endpointAllowed(endpointArn)) {
|
|
147
|
+
throw new NativePushProviderError('InvalidEndpointScope');
|
|
148
|
+
}
|
|
149
|
+
const result = await call(new PublishCommand({
|
|
150
|
+
Message: payload.message,
|
|
151
|
+
MessageAttributes: payload.attributes,
|
|
152
|
+
MessageStructure: 'json',
|
|
153
|
+
TargetArn: endpointArn
|
|
154
|
+
}));
|
|
155
|
+
if (!result.MessageId) {
|
|
156
|
+
throw new NativePushProviderError('MissingProviderMessageId');
|
|
157
|
+
}
|
|
158
|
+
return {
|
|
159
|
+
messageId: result.MessageId
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3IvcGFja2FnZXMvcmVha3Rvci9zcmMvbmF0aXZlUHVzaC9zbnNQcm92aWRlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDcmVhdGVQbGF0Zm9ybUVuZHBvaW50Q29tbWFuZCwgR2V0RW5kcG9pbnRBdHRyaWJ1dGVzQ29tbWFuZCwgUHVibGlzaENvbW1hbmQsIFNldEVuZHBvaW50QXR0cmlidXRlc0NvbW1hbmRcbn0gZnJvbSAnQGF3cy1zZGsvY2xpZW50LXNucyc7XG5cbmltcG9ydCB0eXBlIHtOYXRpdmVQdXNoUGF5bG9hZCwgTmF0aXZlUHVzaFJlZ2lzdHJhdGlvbklucHV0LCBQbGF0Zm9ybUFwcGxpY2F0aW9uQXJucywgU25zU2VuZGVyfSBmcm9tICcuL3R5cGVzLmpzJztcblxuZXhwb3J0IGNsYXNzIE5hdGl2ZVB1c2hQcm92aWRlckVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICByZWFkb25seSBjb2RlOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHRyYW5zaWVudDogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3Rvcihjb2RlOiBzdHJpbmcsIHRyYW5zaWVudCA9IGZhbHNlKSB7XG4gICAgc3VwZXIoYE5hdGl2ZSBwdXNoIHByb3ZpZGVyIGVycm9yOiAke2NvZGV9YCk7XG4gICAgdGhpcy5jb2RlID0gY29kZTtcbiAgICB0aGlzLm5hbWUgPSAnTmF0aXZlUHVzaFByb3ZpZGVyRXJyb3InO1xuICAgIHRoaXMudHJhbnNpZW50ID0gdHJhbnNpZW50O1xuICB9XG59XG5cbmNvbnN0IGVycm9yQ29kZSA9IChlcnJvcjogdW5rbm93bik6IHN0cmluZyA9PiB7XG4gIGNvbnN0IG5hbWUgPSAoZXJyb3IgYXMge25hbWU/OiBzdHJpbmd9KT8ubmFtZTtcbiAgcmV0dXJuIHR5cGVvZiBuYW1lID09PSAnc3RyaW5nJyAmJiAvXltBLVphLXpdezEsODB9JC8udGVzdChuYW1lKSA/IG5hbWUgOiAnVW5rbm93blByb3ZpZGVyRXJyb3InO1xufTtcbmNvbnN0IHRyYW5zaWVudENvZGVzID0gbmV3IFNldChbXG4gICdUaHJvdHRsZWRFeGNlcHRpb24nLCAnVGhyb3R0bGluZ0V4Y2VwdGlvbicsICdJbnRlcm5hbEVycm9yRXhjZXB0aW9uJyxcbiAgJ1NlcnZpY2VVbmF2YWlsYWJsZUV4Y2VwdGlvbicsICdUaW1lb3V0RXJyb3InLCAnTmV0d29ya2luZ0Vycm9yJ1xuXSk7XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVTbnNQdXNoUHJvdmlkZXIgPSAoe1xuICBzbnMsIHBsYXRmb3JtQXBwbGljYXRpb25Bcm5zLCBkZWxheSA9IChtcykgPT4gbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgbXMpKVxufToge1xuICBkZWxheT86IChtaWxsaXNlY29uZHM6IG51bWJlcikgPT4gUHJvbWlzZTx2b2lkPjtcbiAgcGxhdGZvcm1BcHBsaWNhdGlvbkFybnM6IFBsYXRmb3JtQXBwbGljYXRpb25Bcm5zO1xuICBzbnM6IFNuc1NlbmRlcjtcbn0pID0+IHtcbiAgY29uc3QgYXBwbGljYXRpb25Gb3IgPSAoaW5wdXQ6IE5hdGl2ZVB1c2hSZWdpc3RyYXRpb25JbnB1dCk6IHN0cmluZyA9PiB7XG4gICAgbGV0IGFybjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGxldCBleHBlY3RlZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIGlmKGlucHV0LnBsYXRmb3JtID09PSAnQU5EUk9JRCcpIHtcbiAgICAgIGFybiA9IHBsYXRmb3JtQXBwbGljYXRpb25Bcm5zLmFuZHJvaWQ7XG4gICAgICBleHBlY3RlZCA9ICdHQ00nO1xuICAgIH0gZWxzZSBpZihpbnB1dC5wbGF0Zm9ybSA9PT0gJ0lPUycgJiYgaW5wdXQuYXBuc0Vudmlyb25tZW50ID09PSAnc2FuZGJveCcpIHtcbiAgICAgIGFybiA9IHBsYXRmb3JtQXBwbGljYXRpb25Bcm5zLmlvc1NhbmRib3g7XG4gICAgICBleHBlY3RlZCA9ICdBUE5TX1NBTkRCT1gnO1xuICAgIH0gZWxzZSBpZihpbnB1dC5wbGF0Zm9ybSA9PT0gJ0lPUycgJiYgaW5wdXQuYXBuc0Vudmlyb25tZW50ID09PSAncHJvZHVjdGlvbicpIHtcbiAgICAgIGFybiA9IHBsYXRmb3JtQXBwbGljYXRpb25Bcm5zLmlvc1Byb2R1Y3Rpb247XG4gICAgICBleHBlY3RlZCA9ICdBUE5TJztcbiAgICB9XG4gICAgaWYoIWFybiB8fCAhbmV3IFJlZ0V4cChgXmFybjpbYS16MC05LV0rOnNuczpbYS16MC05LV0rOlswLTldezEyfTphcHAvJHtleHBlY3RlZH0vW0EtWmEtejAtOV8uLV0rJGApLnRlc3QoYXJuKSkge1xuICAgICAgdGhyb3cgbmV3IE5hdGl2ZVB1c2hQcm92aWRlckVycm9yKCdJbnZhbGlkQXBwbGljYXRpb25Db25maWd1cmF0aW9uJyk7XG4gICAgfVxuICAgIHJldHVybiBhcm47XG4gIH07XG4gIGNvbnN0IGVuZHBvaW50TWF0Y2hlcyA9IChhcm46IHN0cmluZywgYXBwbGljYXRpb246IHN0cmluZyk6IGJvb2xlYW4gPT4ge1xuICAgIGNvbnN0IHByZWZpeCA9IGAke2FwcGxpY2F0aW9uLnJlcGxhY2UoJzphcHAvJywgJzplbmRwb2ludC8nKX0vYDtcbiAgICByZXR1cm4gYXJuLnN0YXJ0c1dpdGgocHJlZml4KSAmJiAvXltBLVphLXowLTktXSskLy50ZXN0KGFybi5zbGljZShwcmVmaXgubGVuZ3RoKSk7XG4gIH07XG4gIGNvbnN0IGVuZHBvaW50QWxsb3dlZCA9IChhcm46IHN0cmluZyk6IGJvb2xlYW4gPT4gT2JqZWN0LnZhbHVlcyhwbGF0Zm9ybUFwcGxpY2F0aW9uQXJucylcbiAgICAuc29tZSgoYXBwbGljYXRpb24pID0+IGFwcGxpY2F0aW9uICYmIGVuZHBvaW50TWF0Y2hlcyhhcm4sIGFwcGxpY2F0aW9uKSk7XG4gIGNvbnN0IGNhbGwgPSBhc3luYyAoY29tbWFuZDogUGFyYW1ldGVyczxTbnNTZW5kZXJbJ3NlbmQnXT5bMF0pOiBQcm9taXNlPGFueT4gPT4ge1xuICAgIGZvcihsZXQgYXR0ZW1wdCA9IDA7IDsgYXR0ZW1wdCsrKSB7XG4gICAgICB0cnkge1xuICAgICAgICAvLyBTZXF1ZW50aWFsIHJldHJpZXMgZGVsaWJlcmF0ZWx5IHdhaXQgZm9yIHRoZSBwcmVjZWRpbmcgYXR0ZW1wdC5cbiAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3BcbiAgICAgICAgcmV0dXJuIGF3YWl0IHNucy5zZW5kKGNvbW1hbmQgYXMgYW55KTtcbiAgICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgICAgY29uc3QgY29kZSA9IGVycm9yQ29kZShlcnJvcik7XG4gICAgICAgIGlmKHRyYW5zaWVudENvZGVzLmhhcyhjb2RlKSAmJiBhdHRlbXB0IDwgMikge1xuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG4gICAgICAgICAgYXdhaXQgZGVsYXkoMTAwICogKDIgKiogYXR0ZW1wdCkpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHRocm93IG5ldyBOYXRpdmVQdXNoUHJvdmlkZXJFcnJvcihjb2RlLCB0cmFuc2llbnRDb2Rlcy5oYXMoY29kZSkpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbiAgY29uc3QgZW5zdXJlRW5kcG9pbnQgPSBhc3luYyAoaW5wdXQ6IE5hdGl2ZVB1c2hSZWdpc3RyYXRpb25JbnB1dCwgZXhpc3RpbmdFbmRwb2ludEFybj86IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiA9PiB7XG4gICAgY29uc3QgYXBwbGljYXRpb24gPSBhcHBsaWNhdGlvbkZvcihpbnB1dCk7XG4gICAgaWYoIWlucHV0LnRva2VuIHx8IHR5cGVvZiBpbnB1dC50b2tlbiAhPT0gJ3N0cmluZycgfHwgaW5wdXQudG9rZW4ubGVuZ3RoID4gODE5Mikge1xuICAgICAgdGhyb3cgbmV3IE5hdGl2ZVB1c2hQcm92aWRlckVycm9yKCdJbnZhbGlkRGV2aWNlVG9rZW4nKTtcbiAgICB9XG4gICAgaWYoZXhpc3RpbmdFbmRwb2ludEFybiAmJiAhZW5kcG9pbnRNYXRjaGVzKGV4aXN0aW5nRW5kcG9pbnRBcm4sIGFwcGxpY2F0aW9uKSkge1xuICAgICAgdGhyb3cgbmV3IE5hdGl2ZVB1c2hQcm92aWRlckVycm9yKCdJbnZhbGlkRW5kcG9pbnRTY29wZScpO1xuICAgIH1cbiAgICBjb25zdCBjcmVhdGUgPSBhc3luYyAoKTogUHJvbWlzZTxzdHJpbmc+ID0+IHtcbiAgICAgIGxldCBhcm46IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgIGZvcihsZXQgYXR0ZW1wdCA9IDA7IDsgYXR0ZW1wdCsrKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgLy8gS2VlcCB0aGUgQVdTIGR1cGxpY2F0ZS1lbmRwb2ludCBkaWFnbm9zdGljIGxvY2FsOyBuZXZlciBleHBvc2UgaXQgb3IgaXRzIHRva2VuLlxuICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1hd2FpdC1pbi1sb29wXG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc25zLnNlbmQobmV3IENyZWF0ZVBsYXRmb3JtRW5kcG9pbnRDb21tYW5kKHtcbiAgICAgICAgICAgIFBsYXRmb3JtQXBwbGljYXRpb25Bcm46IGFwcGxpY2F0aW9uLCBUb2tlbjogaW5wdXQudG9rZW5cbiAgICAgICAgICB9KSk7XG4gICAgICAgICAgYXJuID0gcmVzdWx0LkVuZHBvaW50QXJuO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGNhdGNoKGVycm9yKSB7XG4gICAgICAgICAgaWYoZXJyb3JDb2RlKGVycm9yKSA9PT0gJ0ludmFsaWRQYXJhbWV0ZXJFeGNlcHRpb24nKSB7XG4gICAgICAgICAgICBjb25zdCBkaWFnbm9zdGljID0gKGVycm9yIGFzIHttZXNzYWdlPzogc3RyaW5nfSkubWVzc2FnZSA/PyAnJztcbiAgICAgICAgICAgIGFybiA9IGRpYWdub3N0aWMubWF0Y2goL0VuZHBvaW50IChhcm46W15cXHNdKykgYWxyZWFkeSBleGlzdHMgd2l0aCB0aGUgc2FtZSBUb2tlbi8pPy5bMV07XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKGFybikge1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmKHRyYW5zaWVudENvZGVzLmhhcyhlcnJvckNvZGUoZXJyb3IpKSAmJiBhdHRlbXB0IDwgMikge1xuICAgICAgICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWF3YWl0LWluLWxvb3BcbiAgICAgICAgICAgIGF3YWl0IGRlbGF5KDEwMCAqICgyICoqIGF0dGVtcHQpKTtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aHJvdyBuZXcgTmF0aXZlUHVzaFByb3ZpZGVyRXJyb3IoZXJyb3JDb2RlKGVycm9yKSwgdHJhbnNpZW50Q29kZXMuaGFzKGVycm9yQ29kZShlcnJvcikpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYoIWFybiB8fCAhZW5kcG9pbnRNYXRjaGVzKGFybiwgYXBwbGljYXRpb24pKSB7XG4gICAgICAgIHRocm93IG5ldyBOYXRpdmVQdXNoUHJvdmlkZXJFcnJvcignSW52YWxpZEVuZHBvaW50U2NvcGUnKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhcm47XG4gICAgfTtcbiAgICBsZXQgYXJuID0gZXhpc3RpbmdFbmRwb2ludEFybiA/PyBhd2FpdCBjcmVhdGUoKTtcbiAgICBsZXQgcmVzdWx0O1xuICAgIHRyeSB7XG4gICAgICByZXN1bHQgPSBhd2FpdCBjYWxsKG5ldyBHZXRFbmRwb2ludEF0dHJpYnV0ZXNDb21tYW5kKHtFbmRwb2ludEFybjogYXJufSkpO1xuICAgIH0gY2F0Y2goZXJyb3IpIHtcbiAgICAgIGlmKChlcnJvciBhcyBOYXRpdmVQdXNoUHJvdmlkZXJFcnJvcikuY29kZSAhPT0gJ05vdEZvdW5kRXhjZXB0aW9uJykge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGFybiA9IGF3YWl0IGNyZWF0ZSgpO1xuICAgICAgcmVzdWx0ID0gYXdhaXQgY2FsbChuZXcgR2V0RW5kcG9pbnRBdHRyaWJ1dGVzQ29tbWFuZCh7RW5kcG9pbnRBcm46IGFybn0pKTtcbiAgICB9XG4gICAgaWYocmVzdWx0LkF0dHJpYnV0ZXM/LlRva2VuICE9PSBpbnB1dC50b2tlbiB8fCByZXN1bHQuQXR0cmlidXRlcz8uRW5hYmxlZCAhPT0gJ3RydWUnKSB7XG4gICAgICBhd2FpdCBjYWxsKG5ldyBTZXRFbmRwb2ludEF0dHJpYnV0ZXNDb21tYW5kKHtBdHRyaWJ1dGVzOiB7RW5hYmxlZDogJ3RydWUnLCBUb2tlbjogaW5wdXQudG9rZW59LCBFbmRwb2ludEFybjogYXJufSkpO1xuICAgIH1cbiAgICByZXR1cm4gYXJuO1xuICB9O1xuICByZXR1cm4ge1xuICAgIGRpc2FibGVFbmRwb2ludDogYXN5bmMgKGVuZHBvaW50QXJuOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgICAgIGlmKCFlbmRwb2ludEFsbG93ZWQoZW5kcG9pbnRBcm4pKSB7XG4gICAgICAgIHRocm93IG5ldyBOYXRpdmVQdXNoUHJvdmlkZXJFcnJvcignSW52YWxpZEVuZHBvaW50U2NvcGUnKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IGNhbGwobmV3IFNldEVuZHBvaW50QXR0cmlidXRlc0NvbW1hbmQoe0F0dHJpYnV0ZXM6IHtFbmFibGVkOiAnZmFsc2UnfSwgRW5kcG9pbnRBcm46IGVuZHBvaW50QXJufSkpO1xuICAgIH0sXG4gICAgZW5zdXJlRW5kcG9pbnQsXG4gICAgcHVibGlzaDogYXN5bmMgKGVuZHBvaW50QXJuOiBzdHJpbmcsIHBheWxvYWQ6IE5hdGl2ZVB1c2hQYXlsb2FkKTogUHJvbWlzZTx7bWVzc2FnZUlkOiBzdHJpbmd9PiA9PiB7XG4gICAgICBpZighZW5kcG9pbnRBbGxvd2VkKGVuZHBvaW50QXJuKSkge1xuICAgICAgICB0aHJvdyBuZXcgTmF0aXZlUHVzaFByb3ZpZGVyRXJyb3IoJ0ludmFsaWRFbmRwb2ludFNjb3BlJyk7XG4gICAgICB9XG4gICAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBjYWxsKG5ldyBQdWJsaXNoQ29tbWFuZCh7TWVzc2FnZTogcGF5bG9hZC5tZXNzYWdlLCBNZXNzYWdlQXR0cmlidXRlczogcGF5bG9hZC5hdHRyaWJ1dGVzLCBNZXNzYWdlU3RydWN0dXJlOiAnanNvbicsIFRhcmdldEFybjogZW5kcG9pbnRBcm59KSk7XG4gICAgICBpZighcmVzdWx0Lk1lc3NhZ2VJZCkge1xuICAgICAgICB0aHJvdyBuZXcgTmF0aXZlUHVzaFByb3ZpZGVyRXJyb3IoJ01pc3NpbmdQcm92aWRlck1lc3NhZ2VJZCcpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHttZXNzYWdlSWQ6IHJlc3VsdC5NZXNzYWdlSWR9O1xuICAgIH1cbiAgfTtcbn07XG4iXSwibmFtZXMiOlsiQ3JlYXRlUGxhdGZvcm1FbmRwb2ludENvbW1hbmQiLCJHZXRFbmRwb2ludEF0dHJpYnV0ZXNDb21tYW5kIiwiUHVibGlzaENvbW1hbmQiLCJTZXRFbmRwb2ludEF0dHJpYnV0ZXNDb21tYW5kIiwiTmF0aXZlUHVzaFByb3ZpZGVyRXJyb3IiLCJFcnJvciIsImNvZGUiLCJ0cmFuc2llbnQiLCJuYW1lIiwiZXJyb3JDb2RlIiwiZXJyb3IiLCJ0ZXN0IiwidHJhbnNpZW50Q29kZXMiLCJTZXQiLCJjcmVhdGVTbnNQdXNoUHJvdmlkZXIiLCJzbnMiLCJwbGF0Zm9ybUFwcGxpY2F0aW9uQXJucyIsImRlbGF5IiwibXMiLCJQcm9taXNlIiwicmVzb2x2ZSIsInNldFRpbWVvdXQiLCJhcHBsaWNhdGlvbkZvciIsImlucHV0IiwiYXJuIiwiZXhwZWN0ZWQiLCJwbGF0Zm9ybSIsImFuZHJvaWQiLCJhcG5zRW52aXJvbm1lbnQiLCJpb3NTYW5kYm94IiwiaW9zUHJvZHVjdGlvbiIsIlJlZ0V4cCIsImVuZHBvaW50TWF0Y2hlcyIsImFwcGxpY2F0aW9uIiwicHJlZml4IiwicmVwbGFjZSIsInN0YXJ0c1dpdGgiLCJzbGljZSIsImxlbmd0aCIsImVuZHBvaW50QWxsb3dlZCIsIk9iamVjdCIsInZhbHVlcyIsInNvbWUiLCJjYWxsIiwiY29tbWFuZCIsImF0dGVtcHQiLCJzZW5kIiwiaGFzIiwiZW5zdXJlRW5kcG9pbnQiLCJleGlzdGluZ0VuZHBvaW50QXJuIiwidG9rZW4iLCJjcmVhdGUiLCJyZXN1bHQiLCJQbGF0Zm9ybUFwcGxpY2F0aW9uQXJuIiwiVG9rZW4iLCJFbmRwb2ludEFybiIsImRpYWdub3N0aWMiLCJtZXNzYWdlIiwibWF0Y2giLCJBdHRyaWJ1dGVzIiwiRW5hYmxlZCIsImRpc2FibGVFbmRwb2ludCIsImVuZHBvaW50QXJuIiwicHVibGlzaCIsInBheWxvYWQiLCJNZXNzYWdlIiwiTWVzc2FnZUF0dHJpYnV0ZXMiLCJhdHRyaWJ1dGVzIiwiTWVzc2FnZVN0cnVjdHVyZSIsIlRhcmdldEFybiIsIk1lc3NhZ2VJZCIsIm1lc3NhZ2VJZCJdLCJtYXBwaW5ncyI6IkFBQUEsU0FDRUEsNkJBQTZCLEVBQUVDLDRCQUE0QixFQUFFQyxjQUFjLEVBQUVDLDRCQUE0QixRQUNwRyxzQkFBc0I7QUFJN0IsT0FBTyxNQUFNQyxnQ0FBZ0NDO0lBQ2xDQyxLQUFhO0lBQ2JDLFVBQW1CO0lBRTVCLFlBQVlELElBQVksRUFBRUMsWUFBWSxLQUFLLENBQUU7UUFDM0MsS0FBSyxDQUFDLENBQUMsNEJBQTRCLEVBQUVELE1BQU07UUFDM0MsSUFBSSxDQUFDQSxJQUFJLEdBQUdBO1FBQ1osSUFBSSxDQUFDRSxJQUFJLEdBQUc7UUFDWixJQUFJLENBQUNELFNBQVMsR0FBR0E7SUFDbkI7QUFDRjtBQUVBLE1BQU1FLFlBQVksQ0FBQ0M7SUFDakIsTUFBTUYsT0FBUUUsT0FBMkJGO0lBQ3pDLE9BQU8sT0FBT0EsU0FBUyxZQUFZLG1CQUFtQkcsSUFBSSxDQUFDSCxRQUFRQSxPQUFPO0FBQzVFO0FBQ0EsTUFBTUksaUJBQWlCLElBQUlDLElBQUk7SUFDN0I7SUFBc0I7SUFBdUI7SUFDN0M7SUFBK0I7SUFBZ0I7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
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { SNSClient } from '@aws-sdk/client-sns';
|
|
2
|
+
export type JsonValue = null | boolean | number | string | JsonValue[] | {
|
|
3
|
+
[key: string]: JsonValue;
|
|
4
|
+
};
|
|
5
|
+
export type PushScope = {
|
|
6
|
+
appId: string;
|
|
7
|
+
environment: string;
|
|
8
|
+
};
|
|
9
|
+
export type PushActor = {
|
|
10
|
+
sessionId: string;
|
|
11
|
+
userId: string;
|
|
12
|
+
};
|
|
13
|
+
export type NativePlatform = 'ANDROID' | 'IOS';
|
|
14
|
+
export type NativePushRegistrationInput = {
|
|
15
|
+
apnsEnvironment?: 'production' | 'sandbox';
|
|
16
|
+
installationId: string;
|
|
17
|
+
platform: NativePlatform;
|
|
18
|
+
token: string;
|
|
19
|
+
};
|
|
20
|
+
export type NativePushRegistration = PushScope & PushActor & Omit<NativePushRegistrationInput, 'token'> & {
|
|
21
|
+
createdAt: string;
|
|
22
|
+
enabled: boolean;
|
|
23
|
+
endpointArn: string;
|
|
24
|
+
registrationId: string;
|
|
25
|
+
revision: number;
|
|
26
|
+
tokenHash: string;
|
|
27
|
+
updatedAt: string;
|
|
28
|
+
};
|
|
29
|
+
export type NativeNotification = {
|
|
30
|
+
body: string;
|
|
31
|
+
createdAt: string;
|
|
32
|
+
data?: Record<string, JsonValue>;
|
|
33
|
+
kind: string;
|
|
34
|
+
notificationId: string;
|
|
35
|
+
title: string;
|
|
36
|
+
version: 1;
|
|
37
|
+
};
|
|
38
|
+
export type NativePushEnvelope = {
|
|
39
|
+
notification: NativeNotification;
|
|
40
|
+
recipientUserId: string;
|
|
41
|
+
scope: PushScope;
|
|
42
|
+
};
|
|
43
|
+
export type NativePushOptions = {
|
|
44
|
+
badge?: number;
|
|
45
|
+
expiresAt?: string;
|
|
46
|
+
};
|
|
47
|
+
export type NativePushPayload = {
|
|
48
|
+
attributes: Record<string, {
|
|
49
|
+
DataType: string;
|
|
50
|
+
StringValue: string;
|
|
51
|
+
}>;
|
|
52
|
+
message: string;
|
|
53
|
+
};
|
|
54
|
+
export type PlatformApplicationArns = {
|
|
55
|
+
android?: string;
|
|
56
|
+
iosProduction?: string;
|
|
57
|
+
iosSandbox?: string;
|
|
58
|
+
};
|
|
59
|
+
export type SnsSender = Pick<SNSClient, 'send'>;
|
|
60
|
+
export type DeliveryOutcome = {
|
|
61
|
+
code?: string;
|
|
62
|
+
providerMessageId?: string;
|
|
63
|
+
registrationId: string;
|
|
64
|
+
status: 'ACCEPTED' | 'INVALID_ENDPOINT' | 'PERMANENT_FAILURE' | 'SKIPPED' | 'TRANSIENT_FAILURE';
|
|
65
|
+
};
|
|
66
|
+
export interface NativePushRepository {
|
|
67
|
+
disableBinding(scope: PushScope, actor: PushActor, registrationId: string, revision?: number): Promise<boolean>;
|
|
68
|
+
disableEndpoint(scope: PushScope, endpointArn: string): Promise<void>;
|
|
69
|
+
hasActiveEndpointBinding(scope: PushScope, endpointArn: string): Promise<boolean>;
|
|
70
|
+
isCurrent(registration: NativePushRegistration): Promise<boolean>;
|
|
71
|
+
listEnabled(scope: PushScope, userId: string): Promise<NativePushRegistration[]>;
|
|
72
|
+
reserveBinding(scope: PushScope, actor: PushActor, input: Omit<NativePushRegistrationInput, 'token'>, tokenHash: string): Promise<number>;
|
|
73
|
+
replaceBinding(scope: PushScope, actor: PushActor, input: Omit<NativePushRegistrationInput, 'token'>, endpointArn: string, tokenHash: string, expectedRevision?: number): Promise<NativePushRegistration>;
|
|
74
|
+
}
|
|
75
|
+
export type NativePushServiceOptions = {
|
|
76
|
+
canDeliver?: (registration: NativePushRegistration, notification: NativeNotification) => Promise<boolean>;
|
|
77
|
+
delay?: (milliseconds: number) => Promise<void>;
|
|
78
|
+
isSessionEligible: (scope: PushScope, actor: PushActor) => Promise<boolean>;
|
|
79
|
+
now?: () => Date;
|
|
80
|
+
platformApplicationArns: PlatformApplicationArns;
|
|
81
|
+
repository: NativePushRepository;
|
|
82
|
+
scope: PushScope;
|
|
83
|
+
sns: SnsSender;
|
|
84
|
+
};
|
|
85
|
+
export interface NativePushService {
|
|
86
|
+
register(actor: PushActor, input: NativePushRegistrationInput): Promise<NativePushRegistration>;
|
|
87
|
+
send(userId: string, notification: NativeNotification, options?: NativePushOptions): Promise<DeliveryOutcome[]>;
|
|
88
|
+
unregister(actor: PushActor, registrationId: string, revision?: number): Promise<boolean>;
|
|
89
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { };
|
|
2
|
+
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3IvcGFja2FnZXMvcmVha3Rvci9zcmMvbmF0aXZlUHVzaC90eXBlcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgdHlwZSB7U05TQ2xpZW50fSBmcm9tICdAYXdzLXNkay9jbGllbnQtc25zJztcblxuZXhwb3J0IHR5cGUgSnNvblZhbHVlID0gbnVsbCB8IGJvb2xlYW4gfCBudW1iZXIgfCBzdHJpbmcgfCBKc29uVmFsdWVbXSB8IHtba2V5OiBzdHJpbmddOiBKc29uVmFsdWV9O1xuZXhwb3J0IHR5cGUgUHVzaFNjb3BlID0ge2FwcElkOiBzdHJpbmc7IGVudmlyb25tZW50OiBzdHJpbmd9O1xuZXhwb3J0IHR5cGUgUHVzaEFjdG9yID0ge3Nlc3Npb25JZDogc3RyaW5nOyB1c2VySWQ6IHN0cmluZ307XG5leHBvcnQgdHlwZSBOYXRpdmVQbGF0Zm9ybSA9ICdBTkRST0lEJyB8ICdJT1MnO1xuZXhwb3J0IHR5cGUgTmF0aXZlUHVzaFJlZ2lzdHJhdGlvbklucHV0ID0ge1xuICBhcG5zRW52aXJvbm1lbnQ/OiAncHJvZHVjdGlvbicgfCAnc2FuZGJveCc7XG4gIGluc3RhbGxhdGlvbklkOiBzdHJpbmc7XG4gIHBsYXRmb3JtOiBOYXRpdmVQbGF0Zm9ybTtcbiAgdG9rZW46IHN0cmluZztcbn07XG5leHBvcnQgdHlwZSBOYXRpdmVQdXNoUmVnaXN0cmF0aW9uID0gUHVzaFNjb3BlICYgUHVzaEFjdG9yICYgT21pdDxOYXRpdmVQdXNoUmVnaXN0cmF0aW9uSW5wdXQsICd0b2tlbic+ICYge1xuICBjcmVhdGVkQXQ6IHN0cmluZztcbiAgZW5hYmxlZDogYm9vbGVhbjtcbiAgZW5kcG9pbnRBcm46IHN0cmluZztcbiAgcmVnaXN0cmF0aW9uSWQ6IHN0cmluZztcbiAgcmV2aXNpb246IG51bWJlcjtcbiAgdG9rZW5IYXNoOiBzdHJpbmc7XG4gIHVwZGF0ZWRBdDogc3RyaW5nO1xufTtcbmV4cG9ydCB0eXBlIE5hdGl2ZU5vdGlmaWNhdGlvbiA9IHtcbiAgYm9keTogc3RyaW5nO1xuICBjcmVhdGVkQXQ6IHN0cmluZztcbiAgZGF0YT86IFJlY29yZDxzdHJpbmcsIEpzb25WYWx1ZT47XG4gIGtpbmQ6IHN0cmluZztcbiAgbm90aWZpY2F0aW9uSWQ6IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbiAgdmVyc2lvbjogMTtcbn07XG5leHBvcnQgdHlwZSBOYXRpdmVQdXNoRW52ZWxvcGUgPSB7bm90aWZpY2F0aW9uOiBOYXRpdmVOb3RpZmljYXRpb247IHJlY2lwaWVudFVzZXJJZDogc3RyaW5nOyBzY29wZTogUHVzaFNjb3BlfTtcbmV4cG9ydCB0eXBlIE5hdGl2ZVB1c2hPcHRpb25zID0ge2JhZGdlPzogbnVtYmVyOyBleHBpcmVzQXQ/OiBzdHJpbmd9O1xuZXhwb3J0IHR5cGUgTmF0aXZlUHVzaFBheWxvYWQgPSB7XG4gIGF0dHJpYnV0ZXM6IFJlY29yZDxzdHJpbmcsIHtEYXRhVHlwZTogc3RyaW5nOyBTdHJpbmdWYWx1ZTogc3RyaW5nfT47XG4gIG1lc3NhZ2U6IHN0cmluZztcbn07XG5leHBvcnQgdHlwZSBQbGF0Zm9ybUFwcGxpY2F0aW9uQXJucyA9IHthbmRyb2lkPzogc3RyaW5nOyBpb3NQcm9kdWN0aW9uPzogc3RyaW5nOyBpb3NTYW5kYm94Pzogc3RyaW5nfTtcbmV4cG9ydCB0eXBlIFNuc1NlbmRlciA9IFBpY2s8U05TQ2xpZW50LCAnc2VuZCc+O1xuZXhwb3J0IHR5cGUgRGVsaXZlcnlPdXRjb21lID0ge1xuICBjb2RlPzogc3RyaW5nO1xuICBwcm92aWRlck1lc3NhZ2VJZD86IHN0cmluZztcbiAgcmVnaXN0cmF0aW9uSWQ6IHN0cmluZztcbiAgc3RhdHVzOiAnQUNDRVBURUQnIHwgJ0lOVkFMSURfRU5EUE9JTlQnIHwgJ1BFUk1BTkVOVF9GQUlMVVJFJyB8ICdTS0lQUEVEJyB8ICdUUkFOU0lFTlRfRkFJTFVSRSc7XG59O1xuZXhwb3J0IGludGVyZmFjZSBOYXRpdmVQdXNoUmVwb3NpdG9yeSB7XG4gIGRpc2FibGVCaW5kaW5nKHNjb3BlOiBQdXNoU2NvcGUsIGFjdG9yOiBQdXNoQWN0b3IsIHJlZ2lzdHJhdGlvbklkOiBzdHJpbmcsIHJldmlzaW9uPzogbnVtYmVyKTogUHJvbWlzZTxib29sZWFuPjtcbiAgZGlzYWJsZUVuZHBvaW50KHNjb3BlOiBQdXNoU2NvcGUsIGVuZHBvaW50QXJuOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+O1xuICBoYXNBY3RpdmVFbmRwb2ludEJpbmRpbmcoc2NvcGU6IFB1c2hTY29wZSwgZW5kcG9pbnRBcm46IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj47XG4gIGlzQ3VycmVudChyZWdpc3RyYXRpb246IE5hdGl2ZVB1c2hSZWdpc3RyYXRpb24pOiBQcm9taXNlPGJvb2xlYW4+O1xuICBsaXN0RW5hYmxlZChzY29wZTogUHVzaFNjb3BlLCB1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8TmF0aXZlUHVzaFJlZ2lzdHJhdGlvbltdPjtcbiAgcmVzZXJ2ZUJpbmRpbmcoc2NvcGU6IFB1c2hTY29wZSwgYWN0b3I6IFB1c2hBY3RvciwgaW5wdXQ6IE9taXQ8TmF0aXZlUHVzaFJlZ2lzdHJhdGlvbklucHV0LCAndG9rZW4nPiwgdG9rZW5IYXNoOiBzdHJpbmcpOiBQcm9taXNlPG51bWJlcj47XG4gIHJlcGxhY2VCaW5kaW5nKHNjb3BlOiBQdXNoU2NvcGUsIGFjdG9yOiBQdXNoQWN0b3IsIGlucHV0OiBPbWl0PE5hdGl2ZVB1c2hSZWdpc3RyYXRpb25JbnB1dCwgJ3Rva2VuJz4sIGVuZHBvaW50QXJuOiBzdHJpbmcsIHRva2VuSGFzaDogc3RyaW5nLCBleHBlY3RlZFJldmlzaW9uPzogbnVtYmVyKTogUHJvbWlzZTxOYXRpdmVQdXNoUmVnaXN0cmF0aW9uPjtcbn1cbmV4cG9ydCB0eXBlIE5hdGl2ZVB1c2hTZXJ2aWNlT3B0aW9ucyA9IHtcbiAgY2FuRGVsaXZlcj86IChyZWdpc3RyYXRpb246IE5hdGl2ZVB1c2hSZWdpc3RyYXRpb24sIG5vdGlmaWNhdGlvbjogTmF0aXZlTm90aWZpY2F0aW9uKSA9PiBQcm9taXNlPGJvb2xlYW4+O1xuICBkZWxheT86IChtaWxsaXNlY29uZHM6IG51bWJlcikgPT4gUHJvbWlzZTx2b2lkPjtcbiAgaXNTZXNzaW9uRWxpZ2libGU6IChzY29wZTogUHVzaFNjb3BlLCBhY3RvcjogUHVzaEFjdG9yKSA9PiBQcm9taXNlPGJvb2xlYW4+O1xuICBub3c/OiAoKSA9PiBEYXRlO1xuICBwbGF0Zm9ybUFwcGxpY2F0aW9uQXJuczogUGxhdGZvcm1BcHBsaWNhdGlvbkFybnM7XG4gIHJlcG9zaXRvcnk6IE5hdGl2ZVB1c2hSZXBvc2l0b3J5O1xuICBzY29wZTogUHVzaFNjb3BlO1xuICBzbnM6IFNuc1NlbmRlcjtcbn07XG5leHBvcnQgaW50ZXJmYWNlIE5hdGl2ZVB1c2hTZXJ2aWNlIHtcbiAgcmVnaXN0ZXIoYWN0b3I6IFB1c2hBY3RvciwgaW5wdXQ6IE5hdGl2ZVB1c2hSZWdpc3RyYXRpb25JbnB1dCk6IFByb21pc2U8TmF0aXZlUHVzaFJlZ2lzdHJhdGlvbj47XG4gIHNlbmQodXNlcklkOiBzdHJpbmcsIG5vdGlmaWNhdGlvbjogTmF0aXZlTm90aWZpY2F0aW9uLCBvcHRpb25zPzogTmF0aXZlUHVzaE9wdGlvbnMpOiBQcm9taXNlPERlbGl2ZXJ5T3V0Y29tZVtdPjtcbiAgdW5yZWdpc3RlcihhY3RvcjogUHVzaEFjdG9yLCByZWdpc3RyYXRpb25JZDogc3RyaW5nLCByZXZpc2lvbj86IG51bWJlcik6IFByb21pc2U8Ym9vbGVhbj47XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBK0RBLFdBSUMifQ==
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { literal } from 'arangojs/aql';
|
|
2
|
+
import type { ApiContext } from '../types/auth.types.js';
|
|
3
|
+
import type { UserType } from '../types/users.types.js';
|
|
4
|
+
/** Recheck atomic enrollment at the legacy write, after an earlier unassociated-account lookup. */
|
|
5
|
+
export declare const organizationAccountWriteGuard: (context: ApiContext, collection: string, variable?: 'doc' | 'u') => ReturnType<typeof literal>;
|
|
6
|
+
/** Protect control-plane accounts under the same lock as ownership changes. */
|
|
7
|
+
export declare const organizationAccountMutation: (context: ApiContext, userId: string, operation: 'deactivate' | 'delete' | 'update', patch: Record<string, unknown>) => Promise<UserType | null>;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/* Stream-transaction steps and ordered retry assertions must execute sequentially. */ /* eslint-disable no-await-in-loop */ import { literal } from 'arangojs/aql';
|
|
2
|
+
import { organizationUserId } from './authorization.js';
|
|
3
|
+
import { activeMemberCount, writeSeatChange } from './membership.js';
|
|
4
|
+
import { organizationEdgeCollections, organizationStoreFor } from './store.js';
|
|
5
|
+
/** Recheck atomic enrollment at the legacy write, after an earlier unassociated-account lookup. */ export const organizationAccountWriteGuard = (context, collection, variable = 'doc')=>literal(collection === 'users' && process.env.ARANGODB_DATABASE && context.databaseName === process.env.ARANGODB_DATABASE ? `${variable}.organizationAccount != true` : 'true');
|
|
6
|
+
/** Protect control-plane accounts under the same lock as ownership changes. */ export const organizationAccountMutation = async (context, userId, operation, patch)=>{
|
|
7
|
+
if (!process.env.ARANGODB_DATABASE || context.databaseName !== process.env.ARANGODB_DATABASE) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
const key = userId.replace(/^users\//, '');
|
|
11
|
+
return organizationStoreFor(context).transaction(async (tx)=>{
|
|
12
|
+
const user = await tx.get('users', key);
|
|
13
|
+
const organizations = await tx.find('organizations', {
|
|
14
|
+
ownerUserId: key
|
|
15
|
+
});
|
|
16
|
+
const related = await tx.find('organizationMemberships', {
|
|
17
|
+
userId: key
|
|
18
|
+
});
|
|
19
|
+
if (!user || !user.organizationAccount && !organizations.length && !related.length) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
if (!context.session?.userId || organizationUserId(context) !== key) {
|
|
23
|
+
throw new Error('account_access_denied');
|
|
24
|
+
}
|
|
25
|
+
if (operation === 'update') {
|
|
26
|
+
if ([
|
|
27
|
+
'organizationAccount',
|
|
28
|
+
'verifiedEmail',
|
|
29
|
+
'verifiedEmailCode',
|
|
30
|
+
'verifiedEmailExpires',
|
|
31
|
+
'verifiedPhone',
|
|
32
|
+
'verifiedPhoneExpires',
|
|
33
|
+
'verifiedSmsCode',
|
|
34
|
+
'email',
|
|
35
|
+
'phone',
|
|
36
|
+
'active',
|
|
37
|
+
'userAccess',
|
|
38
|
+
'salt',
|
|
39
|
+
'type',
|
|
40
|
+
'username',
|
|
41
|
+
'deleted',
|
|
42
|
+
'_key',
|
|
43
|
+
'_id',
|
|
44
|
+
'_rev'
|
|
45
|
+
].some((field)=>patch[field] !== undefined)) {
|
|
46
|
+
throw new Error('protected_account_field');
|
|
47
|
+
}
|
|
48
|
+
if (patch.userId !== undefined && patch.userId !== key || patch.id !== undefined && patch.id !== `users/${key}`) {
|
|
49
|
+
throw new Error('protected_account_field');
|
|
50
|
+
}
|
|
51
|
+
const { id, userId: ignoredUserId, ...safePatch } = patch;
|
|
52
|
+
const updated = {
|
|
53
|
+
...user,
|
|
54
|
+
...safePatch
|
|
55
|
+
};
|
|
56
|
+
await tx.put('users', key, updated, user);
|
|
57
|
+
return updated;
|
|
58
|
+
}
|
|
59
|
+
if (organizations.length) {
|
|
60
|
+
throw new Error('ownership_transfer_required');
|
|
61
|
+
}
|
|
62
|
+
const memberships = related.filter((membership)=>membership.status === 'active');
|
|
63
|
+
for (const membership of memberships){
|
|
64
|
+
const org = await tx.get('organizations', membership.organizationId);
|
|
65
|
+
if (!org) {
|
|
66
|
+
throw new Error('organization_state_invalid');
|
|
67
|
+
}
|
|
68
|
+
const previousCount = await activeMemberCount(tx, org.organizationId);
|
|
69
|
+
await tx.put('organizationMemberships', membership._key, {
|
|
70
|
+
...membership,
|
|
71
|
+
revision: membership.revision + 1,
|
|
72
|
+
status: 'deactivated',
|
|
73
|
+
updatedAt: Date.now()
|
|
74
|
+
}, membership);
|
|
75
|
+
await writeSeatChange(tx, org, previousCount - 1, Date.now(), previousCount);
|
|
76
|
+
}
|
|
77
|
+
if (operation === 'delete') {
|
|
78
|
+
for (const collection of organizationEdgeCollections){
|
|
79
|
+
const edges = [
|
|
80
|
+
...await tx.find(collection, {
|
|
81
|
+
_from: `users/${key}`
|
|
82
|
+
}),
|
|
83
|
+
...await tx.find(collection, {
|
|
84
|
+
_to: `users/${key}`
|
|
85
|
+
})
|
|
86
|
+
];
|
|
87
|
+
const unique = new Map(edges.map((edge)=>[
|
|
88
|
+
edge._key,
|
|
89
|
+
edge
|
|
90
|
+
]));
|
|
91
|
+
for (const edge of unique.values()){
|
|
92
|
+
await tx.remove(collection, edge);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
await tx.remove('users', user);
|
|
96
|
+
} else {
|
|
97
|
+
await tx.put('users', key, {
|
|
98
|
+
...user,
|
|
99
|
+
active: false
|
|
100
|
+
}, user);
|
|
101
|
+
}
|
|
102
|
+
return user;
|
|
103
|
+
});
|
|
104
|
+
}; /* Stream-transaction steps and ordered retry assertions must execute sequentially. */ /* ArangoDB document metadata uses these reserved field names. */ /* eslint no-underscore-dangle: ["warn", {"allow": ["_key", "_rev", "_id"]}] */
|
|
105
|
+
|
|
106
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9uaXRyb2c3L0RldmVsb3BtZW50L3JlYWt0b3IvcGFja2FnZXMvcmVha3Rvci9zcmMvb3JnYW5pemF0aW9ucy9hY2NvdW50TGlmZWN5Y2xlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIFN0cmVhbS10cmFuc2FjdGlvbiBzdGVwcyBhbmQgb3JkZXJlZCByZXRyeSBhc3NlcnRpb25zIG11c3QgZXhlY3V0ZSBzZXF1ZW50aWFsbHkuICovXG4vKiBlc2xpbnQtZGlzYWJsZSBuby1hd2FpdC1pbi1sb29wICovXG5pbXBvcnQge2xpdGVyYWx9IGZyb20gJ2FyYW5nb2pzL2FxbCc7XG5cbmltcG9ydCB7b3JnYW5pemF0aW9uVXNlcklkfSBmcm9tICcuL2F1dGhvcml6YXRpb24uanMnO1xuaW1wb3J0IHthY3RpdmVNZW1iZXJDb3VudCwgd3JpdGVTZWF0Q2hhbmdlfSBmcm9tICcuL21lbWJlcnNoaXAuanMnO1xuaW1wb3J0IHtvcmdhbml6YXRpb25FZGdlQ29sbGVjdGlvbnMsIG9yZ2FuaXphdGlvblN0b3JlRm9yfSBmcm9tICcuL3N0b3JlLmpzJztcblxuaW1wb3J0IHR5cGUge0FwaUNvbnRleHR9IGZyb20gJy4uL3R5cGVzL2F1dGgudHlwZXMuanMnO1xuaW1wb3J0IHR5cGUge1VzZXJUeXBlfSBmcm9tICcuLi90eXBlcy91c2Vycy50eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7T3JnYW5pemF0aW9uLCBPcmdhbml6YXRpb25NZW1iZXJzaGlwfSBmcm9tICcuL3R5cGVzLmpzJztcblxuLyoqIFJlY2hlY2sgYXRvbWljIGVucm9sbG1lbnQgYXQgdGhlIGxlZ2FjeSB3cml0ZSwgYWZ0ZXIgYW4gZWFybGllciB1bmFzc29jaWF0ZWQtYWNjb3VudCBsb29rdXAuICovXG5leHBvcnQgY29uc3Qgb3JnYW5pemF0aW9uQWNjb3VudFdyaXRlR3VhcmQgPSAoXG4gIGNvbnRleHQ6IEFwaUNvbnRleHQsIGNvbGxlY3Rpb246IHN0cmluZywgdmFyaWFibGU6ICdkb2MnIHwgJ3UnID0gJ2RvYydcbik6IFJldHVyblR5cGU8dHlwZW9mIGxpdGVyYWw+ID0+IGxpdGVyYWwoXG4gIGNvbGxlY3Rpb24gPT09ICd1c2VycycgJiYgcHJvY2Vzcy5lbnYuQVJBTkdPREJfREFUQUJBU0UgJiYgY29udGV4dC5kYXRhYmFzZU5hbWUgPT09IHByb2Nlc3MuZW52LkFSQU5HT0RCX0RBVEFCQVNFXG4gICAgPyBgJHt2YXJpYWJsZX0ub3JnYW5pemF0aW9uQWNjb3VudCAhPSB0cnVlYCA6ICd0cnVlJ1xuKTtcblxuLyoqIFByb3RlY3QgY29udHJvbC1wbGFuZSBhY2NvdW50cyB1bmRlciB0aGUgc2FtZSBsb2NrIGFzIG93bmVyc2hpcCBjaGFuZ2VzLiAqL1xuZXhwb3J0IGNvbnN0IG9yZ2FuaXphdGlvbkFjY291bnRNdXRhdGlvbiA9IGFzeW5jIChcbiAgY29udGV4dDogQXBpQ29udGV4dCxcbiAgdXNlcklkOiBzdHJpbmcsXG4gIG9wZXJhdGlvbjogJ2RlYWN0aXZhdGUnIHwgJ2RlbGV0ZScgfCAndXBkYXRlJyxcbiAgcGF0Y2g6IFJlY29yZDxzdHJpbmcsIHVua25vd24+XG4pOiBQcm9taXNlPFVzZXJUeXBlIHwgbnVsbD4gPT4ge1xuICBpZighcHJvY2Vzcy5lbnYuQVJBTkdPREJfREFUQUJBU0UgfHwgY29udGV4dC5kYXRhYmFzZU5hbWUgIT09IHByb2Nlc3MuZW52LkFSQU5HT0RCX0RBVEFCQVNFKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3Qga2V5ID0gdXNlcklkLnJlcGxhY2UoL151c2Vyc1xcLy8sICcnKTtcbiAgcmV0dXJuIG9yZ2FuaXphdGlvblN0b3JlRm9yKGNvbnRleHQpLnRyYW5zYWN0aW9uKGFzeW5jICh0eCkgPT4ge1xuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCB0eC5nZXQ8VXNlclR5cGUgJiB7b3JnYW5pemF0aW9uQWNjb3VudD86IGJvb2xlYW59PigndXNlcnMnLCBrZXkpO1xuICAgIGNvbnN0IG9yZ2FuaXphdGlvbnMgPSBhd2FpdCB0eC5maW5kPE9yZ2FuaXphdGlvbj4oJ29yZ2FuaXphdGlvbnMnLCB7b3duZXJVc2VySWQ6IGtleX0pO1xuICAgIGNvbnN0IHJlbGF0ZWQgPSBhd2FpdCB0eC5maW5kPE9yZ2FuaXphdGlvbk1lbWJlcnNoaXA+KCdvcmdhbml6YXRpb25NZW1iZXJzaGlwcycsIHt1c2VySWQ6IGtleX0pO1xuICAgIGlmKCF1c2VyIHx8ICghdXNlci5vcmdhbml6YXRpb25BY2NvdW50ICYmICFvcmdhbml6YXRpb25zLmxlbmd0aCAmJiAhcmVsYXRlZC5sZW5ndGgpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgaWYoIWNvbnRleHQuc2Vzc2lvbj8udXNlcklkIHx8IG9yZ2FuaXphdGlvblVzZXJJZChjb250ZXh0KSAhPT0ga2V5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FjY291bnRfYWNjZXNzX2RlbmllZCcpO1xuICAgIH1cbiAgICBpZihvcGVyYXRpb24gPT09ICd1cGRhdGUnKSB7XG4gICAgICBpZihcbiAgICAgICAgW1xuICAgICAgICAgICdvcmdhbml6YXRpb25BY2NvdW50JyxcbiAgICAgICAgICAndmVyaWZpZWRFbWFpbCcsXG4gICAgICAgICAgJ3ZlcmlmaWVkRW1haWxDb2RlJyxcbiAgICAgICAgICAndmVyaWZpZWRFbWFpbEV4cGlyZXMnLFxuICAgICAgICAgICd2ZXJpZmllZFBob25lJyxcbiAgICAgICAgICAndmVyaWZpZWRQaG9uZUV4cGlyZXMnLFxuICAgICAgICAgICd2ZXJpZmllZFNtc0NvZGUnLFxuICAgICAgICAgICdlbWFpbCcsXG4gICAgICAgICAgJ3Bob25lJyxcbiAgICAgICAgICAnYWN0aXZlJyxcbiAgICAgICAgICAndXNlckFjY2VzcycsXG4gICAgICAgICAgJ3NhbHQnLFxuICAgICAgICAgICd0eXBlJyxcbiAgICAgICAgICAndXNlcm5hbWUnLFxuICAgICAgICAgICdkZWxldGVkJyxcbiAgICAgICAgICAnX2tleScsXG4gICAgICAgICAgJ19pZCcsXG4gICAgICAgICAgJ19yZXYnXG4gICAgICAgIF0uc29tZSgoZmllbGQpID0+IHBhdGNoW2ZpZWxkXSAhPT0gdW5kZWZpbmVkKVxuICAgICAgKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncHJvdGVjdGVkX2FjY291bnRfZmllbGQnKTtcbiAgICAgIH1cbiAgICAgIGlmKFxuICAgICAgICAocGF0Y2gudXNlcklkICE9PSB1bmRlZmluZWQgJiYgcGF0Y2gudXNlcklkICE9PSBrZXkpIHx8XG4gICAgICAgIChwYXRjaC5pZCAhPT0gdW5kZWZpbmVkICYmIHBhdGNoLmlkICE9PSBgdXNlcnMvJHtrZXl9YClcbiAgICAgICkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb3RlY3RlZF9hY2NvdW50X2ZpZWxkJyk7XG4gICAgICB9XG4gICAgICBjb25zdCB7aWQsIHVzZXJJZDogaWdub3JlZFVzZXJJZCwgLi4uc2FmZVBhdGNofSA9IHBhdGNoO1xuICAgICAgY29uc3QgdXBkYXRlZCA9IHsuLi51c2VyLCAuLi5zYWZlUGF0Y2h9O1xuICAgICAgYXdhaXQgdHgucHV0KCd1c2VycycsIGtleSwgdXBkYXRlZCwgdXNlcik7XG4gICAgICByZXR1cm4gdXBkYXRlZDtcbiAgICB9XG4gICAgaWYob3JnYW5pemF0aW9ucy5sZW5ndGgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignb3duZXJzaGlwX3RyYW5zZmVyX3JlcXVpcmVkJyk7XG4gICAgfVxuICAgIGNvbnN0IG1lbWJlcnNoaXBzID0gcmVsYXRlZC5maWx0ZXIoKG1lbWJlcnNoaXApID0+IG1lbWJlcnNoaXAuc3RhdHVzID09PSAnYWN0aXZlJyk7XG4gICAgZm9yKGNvbnN0IG1lbWJlcnNoaXAgb2YgbWVtYmVyc2hpcHMpIHtcbiAgICAgIGNvbnN0IG9yZyA9IGF3YWl0IHR4LmdldDxPcmdhbml6YXRpb24+KCdvcmdhbml6YXRpb25zJywgbWVtYmVyc2hpcC5vcmdhbml6YXRpb25JZCk7XG4gICAgICBpZighb3JnKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcignb3JnYW5pemF0aW9uX3N0YXRlX2ludmFsaWQnKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHByZXZpb3VzQ291bnQgPSBhd2FpdCBhY3RpdmVNZW1iZXJDb3VudCh0eCwgb3JnLm9yZ2FuaXphdGlvbklkKTtcbiAgICAgIGF3YWl0IHR4LnB1dChcbiAgICAgICAgJ29yZ2FuaXphdGlvbk1lbWJlcnNoaXBzJyxcbiAgICAgICAgbWVtYmVyc2hpcC5fa2V5LFxuICAgICAgICB7Li4ubWVtYmVyc2hpcCwgcmV2aXNpb246IG1lbWJlcnNoaXAucmV2aXNpb24gKyAxLCBzdGF0dXM6ICdkZWFjdGl2YXRlZCcsIHVwZGF0ZWRBdDogRGF0ZS5ub3coKX0sXG4gICAgICAgIG1lbWJlcnNoaXBcbiAgICAgICk7XG4gICAgICBhd2FpdCB3cml0ZVNlYXRDaGFuZ2UodHgsIG9yZywgcHJldmlvdXNDb3VudCAtIDEsIERhdGUubm93KCksIHByZXZpb3VzQ291bnQpO1xuICAgIH1cbiAgICBpZihvcGVyYXRpb24gPT09ICdkZWxldGUnKSB7XG4gICAgICBmb3IoY29uc3QgY29sbGVjdGlvbiBvZiBvcmdhbml6YXRpb25FZGdlQ29sbGVjdGlvbnMpIHtcbiAgICAgICAgY29uc3QgZWRnZXMgPSBbXG4gICAgICAgICAgLi4uKGF3YWl0IHR4LmZpbmQoY29sbGVjdGlvbiwge19mcm9tOiBgdXNlcnMvJHtrZXl9YH0pKSxcbiAgICAgICAgICAuLi4oYXdhaXQgdHguZmluZChjb2xsZWN0aW9uLCB7X3RvOiBgdXNlcnMvJHtrZXl9YH0pKVxuICAgICAgICBdO1xuICAgICAgICBjb25zdCB1bmlxdWUgPSBuZXcgTWFwKGVkZ2VzLm1hcCgoZWRnZSkgPT4gW2VkZ2UuX2tleSwgZWRnZV0pKTtcbiAgICAgICAgZm9yKGNvbnN0IGVkZ2Ugb2YgdW5pcXVlLnZhbHVlcygpKSB7XG4gICAgICAgICAgYXdhaXQgdHgucmVtb3ZlKGNvbGxlY3Rpb24sIGVkZ2UpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBhd2FpdCB0eC5yZW1vdmUoJ3VzZXJzJywgdXNlcik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHR4LnB1dCgndXNlcnMnLCBrZXksIHsuLi51c2VyLCBhY3RpdmU6IGZhbHNlfSwgdXNlcik7XG4gICAgfVxuICAgIHJldHVybiB1c2VyO1xuICB9KTtcbn07XG4vKiBTdHJlYW0tdHJhbnNhY3Rpb24gc3RlcHMgYW5kIG9yZGVyZWQgcmV0cnkgYXNzZXJ0aW9ucyBtdXN0IGV4ZWN1dGUgc2VxdWVudGlhbGx5LiAqL1xuXG4vKiBBcmFuZ29EQiBkb2N1bWVudCBtZXRhZGF0YSB1c2VzIHRoZXNlIHJlc2VydmVkIGZpZWxkIG5hbWVzLiAqL1xuLyogZXNsaW50IG5vLXVuZGVyc2NvcmUtZGFuZ2xlOiBbXCJ3YXJuXCIsIHtcImFsbG93XCI6IFtcIl9rZXlcIiwgXCJfcmV2XCIsIFwiX2lkXCJdfV0gKi9cbiJdLCJuYW1lcyI6WyJsaXRlcmFsIiwib3JnYW5pemF0aW9uVXNlcklkIiwiYWN0aXZlTWVtYmVyQ291bnQiLCJ3cml0ZVNlYXRDaGFuZ2UiLCJvcmdhbml6YXRpb25FZGdlQ29sbGVjdGlvbnMiLCJvcmdhbml6YXRpb25TdG9yZUZvciIsIm9yZ2FuaXphdGlvbkFjY291bnRXcml0ZUd1YXJkIiwiY29udGV4dCIsImNvbGxlY3Rpb24iLCJ2YXJpYWJsZSIsInByb2Nlc3MiLCJlbnYiLCJBUkFOR09EQl9EQVRBQkFTRSIsImRhdGFiYXNlTmFtZSIsIm9yZ2FuaXphdGlvbkFjY291bnRNdXRhdGlvbiIsInVzZXJJZCIsIm9wZXJhdGlvbiIsInBhdGNoIiwia2V5IiwicmVwbGFjZSIsInRyYW5zYWN0aW9uIiwidHgiLCJ1c2VyIiwiZ2V0Iiwib3JnYW5pemF0aW9ucyIsImZpbmQiLCJvd25lclVzZXJJZCIsInJlbGF0ZWQiLCJvcmdhbml6YXRpb25BY2NvdW50IiwibGVuZ3RoIiwic2Vzc2lvbiIsIkVycm9yIiwic29tZSIsImZpZWxkIiwidW5kZWZpbmVkIiwiaWQiLCJpZ25vcmVkVXNlcklkIiwic2FmZVBhdGNoIiwidXBkYXRlZCIsInB1dCIsIm1lbWJlcnNoaXBzIiwiZmlsdGVyIiwibWVtYmVyc2hpcCIsInN0YXR1cyIsIm9yZyIsIm9yZ2FuaXphdGlvbklkIiwicHJldmlvdXNDb3VudCIsIl9rZXkiLCJyZXZpc2lvbiIsInVwZGF0ZWRBdCIsIkRhdGUiLCJub3ciLCJlZGdlcyIsIl9mcm9tIiwiX3RvIiwidW5pcXVlIiwiTWFwIiwibWFwIiwiZWRnZSIsInZhbHVlcyIsInJlbW92ZSIsImFjdGl2ZSJdLCJtYXBwaW5ncyI6IkFBQUEsb0ZBQW9GLEdBQ3BGLG1DQUFtQyxHQUNuQyxTQUFRQSxPQUFPLFFBQU8sZUFBZTtBQUVyQyxTQUFRQyxrQkFBa0IsUUFBTyxxQkFBcUI7QUFDdEQsU0FBUUMsaUJBQWlCLEVBQUVDLGVBQWUsUUFBTyxrQkFBa0I7QUFDbkUsU0FBUUMsMkJBQTJCLEVBQUVDLG9CQUFvQixRQUFPLGFBQWE7QUFNN0UsaUdBQWlHLEdBQ2pHLE9BQU8sTUFBTUMsZ0NBQWdDLENBQzNDQyxTQUFxQkMsWUFBb0JDLFdBQXdCLEtBQUssR0FDdkNULFFBQy9CUSxlQUFlLFdBQVdFLFFBQVFDLEdBQUcsQ0FBQ0MsaUJBQWlCLElBQUlMLFFBQVFNLFlBQVksS0FBS0gsUUFBUUMsR0FBRyxDQUFDQyxpQkFBaUIsR0FDN0csR0FBR0gsU0FBUyw0QkFBNEIsQ0FBQyxHQUFHLFFBQ2hEO0FBRUYsNkVBQTZFLEdBQzdFLE9BQU8sTUFBTUssOEJBQThCLE9BQ3pDUCxTQUNBUSxRQUNBQyxXQUNBQztJQUVBLElBQUcsQ0FBQ1AsUUFBUUMsR0FBRyxDQUFDQyxpQkFBaUIsSUFBSUwsUUFBUU0sWUFBWSxLQUFLSCxRQUFRQyxHQUFHLENBQUNDLGlCQUFpQixFQUFFO1FBQzNGLE9BQU87SUFDVDtJQUNBLE1BQU1NLE1BQU1ILE9BQU9JLE9BQU8sQ0FBQyxZQUFZO0lBQ3ZDLE9BQU9kLHFCQUFxQkUsU0FBU2EsV0FBVyxDQUFDLE9BQU9DO1FBQ3RELE1BQU1DLE9BQU8sTUFBTUQsR0FBR0UsR0FBRyxDQUE2QyxT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
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type OrganizationTransaction } from './store.js';
|
|
2
|
+
import type { ApiContext } from '../types/auth.types.js';
|
|
3
|
+
import type { Organization, OrganizationAccess } from './types.js';
|
|
4
|
+
export declare const organizationUserId: (context: ApiContext) => string;
|
|
5
|
+
export declare const organizationAccessInTransaction: (tx: OrganizationTransaction, context: ApiContext, organizationId: string, role: 'member' | 'admin' | 'owner') => Promise<OrganizationAccess>;
|
|
6
|
+
export declare const requireOrganizationAccess: (context: ApiContext, organizationId: string, role: 'member' | 'admin' | 'owner') => Promise<OrganizationAccess>;
|
|
7
|
+
export declare const listOrganizations: (context: ApiContext) => Promise<(Organization & {
|
|
8
|
+
canManage: boolean;
|
|
9
|
+
})[]>;
|