@astralbeam/sdk 0.7.0 → 0.10.1
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 +45 -53
- package/dist/api-CaNIR6Af.js +296 -0
- package/dist/api.d.ts +333 -0
- package/dist/api.js +2 -0
- package/dist/client.d.ts +5 -5
- package/dist/client.js +1 -1
- package/dist/{core-BF1G1dLe.js → core-Dr2IDA6j.js} +33 -33
- package/dist/core.d.ts +1 -1
- package/dist/core.js +1 -1
- package/dist/debug-BSzSiibd.js +1 -0
- package/dist/{index-CudekMKM.d.ts → index-BQBdZKyB.d.ts} +5 -5
- package/dist/react.d.ts +3 -3
- package/dist/react.js +5 -4
- package/dist/server.d.ts +18 -4
- package/dist/server.js +24 -7
- package/dist/widget-B6YT3G1i.js +79 -0
- package/package.json +15 -4
- package/dist/debug-DyjRg3e0.js +0 -1
- package/dist/widget-PZ-6BF36.js +0 -79
package/dist/server.d.ts
CHANGED
|
@@ -25,18 +25,32 @@ interface TenantUser {
|
|
|
25
25
|
readonly admin?: boolean | undefined;
|
|
26
26
|
readonly metadata?: JsonMetadata | undefined;
|
|
27
27
|
}
|
|
28
|
-
interface
|
|
28
|
+
interface CreateAstralBeamTokenOptions<TTenantUser extends TenantUser = TenantUser, TTenant extends Tenant = Tenant> {
|
|
29
29
|
readonly apiKey: string;
|
|
30
30
|
readonly user: TTenantUser;
|
|
31
31
|
readonly tenant: TTenant;
|
|
32
32
|
readonly expiresInSeconds?: number | undefined;
|
|
33
33
|
}
|
|
34
|
+
interface CreateAstralBeamOrganizationTokenOptions {
|
|
35
|
+
readonly apiKey: string;
|
|
36
|
+
/** Host-authenticated email of an existing organization member, never browser-supplied identity. */
|
|
37
|
+
readonly email: string;
|
|
38
|
+
readonly organizationId: string;
|
|
39
|
+
readonly expiresInSeconds?: number | undefined;
|
|
40
|
+
}
|
|
41
|
+
/** Delegates a member's current database permissions. Does not restrict the API-key holder's authority. */
|
|
42
|
+
declare function createAstralBeamOrganizationToken({
|
|
43
|
+
apiKey,
|
|
44
|
+
email,
|
|
45
|
+
organizationId,
|
|
46
|
+
expiresInSeconds
|
|
47
|
+
}: CreateAstralBeamOrganizationTokenOptions): Promise<string>;
|
|
34
48
|
/** Creates the short-lived bearer token returned by an application's server auth endpoint. */
|
|
35
|
-
declare function
|
|
49
|
+
declare function createAstralBeamToken<TTenantUser extends TenantUser = TenantUser, TTenant extends Tenant = Tenant>({
|
|
36
50
|
apiKey,
|
|
37
51
|
user,
|
|
38
52
|
tenant,
|
|
39
53
|
expiresInSeconds
|
|
40
|
-
}:
|
|
54
|
+
}: CreateAstralBeamTokenOptions<TTenantUser, TTenant>): Promise<string>;
|
|
41
55
|
//#endregion
|
|
42
|
-
export { CHAT_AUTH_TOKEN_AUDIENCE, CHAT_AUTH_TOKEN_LIFETIME_SECONDS, CHAT_AUTH_TOKEN_MAX_LIFETIME_SECONDS, CHAT_AUTH_TOKEN_TYPE, CHAT_AUTH_TOKEN_VERSION,
|
|
56
|
+
export { CHAT_AUTH_TOKEN_AUDIENCE, CHAT_AUTH_TOKEN_LIFETIME_SECONDS, CHAT_AUTH_TOKEN_MAX_LIFETIME_SECONDS, CHAT_AUTH_TOKEN_TYPE, CHAT_AUTH_TOKEN_VERSION, CreateAstralBeamOrganizationTokenOptions, CreateAstralBeamTokenOptions, JsonMetadata, JsonValue, Tenant, TenantUser, createAstralBeamOrganizationToken, createAstralBeamToken };
|
package/dist/server.js
CHANGED
|
@@ -645,7 +645,7 @@ const CHAT_AUTH_TOKEN_MAX_LIFETIME_SECONDS = 600;
|
|
|
645
645
|
const CHAT_AUTH_TOKEN_MAX_BYTES = 16384;
|
|
646
646
|
const IDENTITY_MAX_BYTES = 8192;
|
|
647
647
|
const EXTERNAL_ID_MAX_LENGTH = 255;
|
|
648
|
-
const API_KEY_PATTERN = /^key_[0-9a-
|
|
648
|
+
const API_KEY_PATTERN = /^key_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}_[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}_abo_[A-Za-z]{64}$/;
|
|
649
649
|
const TENANT_FIELDS = [
|
|
650
650
|
"id",
|
|
651
651
|
"name",
|
|
@@ -659,13 +659,13 @@ const TENANT_USER_FIELDS = [
|
|
|
659
659
|
];
|
|
660
660
|
const textEncoder = new TextEncoder();
|
|
661
661
|
function parseApiKey(apiKey) {
|
|
662
|
-
if (!API_KEY_PATTERN.test(apiKey)) throw new Error("apiKey must match key_<
|
|
662
|
+
if (!API_KEY_PATTERN.test(apiKey)) throw new Error("apiKey must match key_<organizationId>_<id>_abo_<secret>");
|
|
663
663
|
const separator = apiKey.lastIndexOf("_abo_");
|
|
664
664
|
const keyId = apiKey.slice(0, separator);
|
|
665
665
|
const keySecret = apiKey.slice(separator + 1);
|
|
666
666
|
return {
|
|
667
667
|
keyId,
|
|
668
|
-
|
|
668
|
+
organizationId: keyId.slice(4, keyId.indexOf("_", 4)),
|
|
669
669
|
keySecret
|
|
670
670
|
};
|
|
671
671
|
}
|
|
@@ -704,10 +704,27 @@ async function signingKey(secret) {
|
|
|
704
704
|
const digest = await crypto.subtle.digest("SHA-256", textEncoder.encode(secret));
|
|
705
705
|
return textEncoder.encode(encode(new Uint8Array(digest)));
|
|
706
706
|
}
|
|
707
|
+
/** Delegates a member's current database permissions. Does not restrict the API-key holder's authority. */
|
|
708
|
+
async function createAstralBeamOrganizationToken({ apiKey, email, organizationId, expiresInSeconds = 300 }) {
|
|
709
|
+
if (typeof email !== "string" || email.length > 320 || email.includes("\0") || !/^[^\s@]+@[^\s@]+$/.test(email)) throw new Error("email must be an email address of at most 320 characters");
|
|
710
|
+
if (!Number.isInteger(expiresInSeconds) || expiresInSeconds < 60 || expiresInSeconds > 600) throw new Error("organization auth tokens must live for 60-600 seconds");
|
|
711
|
+
const { keyId, organizationId: keyOrganizationId, keySecret } = parseApiKey(apiKey);
|
|
712
|
+
if (organizationId !== keyOrganizationId) throw new Error("organizationId must match the API key organization");
|
|
713
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
714
|
+
return await new SignJWT({
|
|
715
|
+
ver: 1,
|
|
716
|
+
email,
|
|
717
|
+
organization_id: organizationId
|
|
718
|
+
}).setProtectedHeader({
|
|
719
|
+
alg: "HS256",
|
|
720
|
+
typ: "astralbeam-organization+jwt",
|
|
721
|
+
kid: keyId
|
|
722
|
+
}).setIssuer(organizationId).setAudience(CHAT_AUTH_TOKEN_AUDIENCE).setIssuedAt(now).setExpirationTime(now + expiresInSeconds).sign(await signingKey(keySecret));
|
|
723
|
+
}
|
|
707
724
|
/** Creates the short-lived bearer token returned by an application's server auth endpoint. */
|
|
708
|
-
async function
|
|
725
|
+
async function createAstralBeamToken({ apiKey, user, tenant, expiresInSeconds = 300 }) {
|
|
709
726
|
if (!Number.isInteger(expiresInSeconds) || expiresInSeconds < 60 || expiresInSeconds > 600) throw new Error("chat auth tokens must live for 60-600 seconds");
|
|
710
|
-
const { keyId,
|
|
727
|
+
const { keyId, organizationId, keySecret } = parseApiKey(apiKey);
|
|
711
728
|
const identity = validatedIdentity(user, tenant);
|
|
712
729
|
const now = Math.floor(Date.now() / 1e3);
|
|
713
730
|
const token = await new SignJWT({
|
|
@@ -718,9 +735,9 @@ async function createChatAuthToken({ apiKey, user, tenant, expiresInSeconds = 30
|
|
|
718
735
|
alg: "HS256",
|
|
719
736
|
typ: CHAT_AUTH_TOKEN_TYPE,
|
|
720
737
|
kid: keyId
|
|
721
|
-
}).setIssuer(
|
|
738
|
+
}).setIssuer(organizationId).setAudience(CHAT_AUTH_TOKEN_AUDIENCE).setIssuedAt(now).setExpirationTime(now + expiresInSeconds).sign(await signingKey(keySecret));
|
|
722
739
|
if (textEncoder.encode(token).byteLength > CHAT_AUTH_TOKEN_MAX_BYTES) throw new Error(`chat auth tokens must not exceed ${CHAT_AUTH_TOKEN_MAX_BYTES} bytes`);
|
|
723
740
|
return token;
|
|
724
741
|
}
|
|
725
742
|
//#endregion
|
|
726
|
-
export { CHAT_AUTH_TOKEN_AUDIENCE, CHAT_AUTH_TOKEN_LIFETIME_SECONDS, CHAT_AUTH_TOKEN_MAX_LIFETIME_SECONDS, CHAT_AUTH_TOKEN_TYPE, CHAT_AUTH_TOKEN_VERSION,
|
|
743
|
+
export { CHAT_AUTH_TOKEN_AUDIENCE, CHAT_AUTH_TOKEN_LIFETIME_SECONDS, CHAT_AUTH_TOKEN_MAX_LIFETIME_SECONDS, CHAT_AUTH_TOKEN_TYPE, CHAT_AUTH_TOKEN_VERSION, createAstralBeamOrganizationToken, createAstralBeamToken };
|