@teamvortexsoftware/vortex-node-22-sdk 0.0.3 → 0.0.5
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 +4 -4
- package/dist/index.d.mts +95 -0
- package/dist/index.d.ts +95 -3
- package/dist/index.js +174 -15
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +140 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +9 -7
- package/dist/index.d.ts.map +0 -1
- package/dist/types.d.ts +0 -46
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -2
- package/dist/vortex.d.ts +0 -35
- package/dist/vortex.d.ts.map +0 -1
- package/dist/vortex.js +0 -217
package/README.md
CHANGED
|
@@ -44,9 +44,9 @@ const identifiers = [
|
|
|
44
44
|
|
|
45
45
|
// groups are specific to your product. This list should be the groups that the current requesting user is a part of. It is up to you to define them if you so choose. Based on the values here, we can determine whether or not the user is allowed to invite others to a particular group
|
|
46
46
|
const groups = [
|
|
47
|
-
{ type: 'workspace',
|
|
48
|
-
{ type: 'document',
|
|
49
|
-
{ type: 'document',
|
|
47
|
+
{ type: 'workspace', groupId: 'some-workspace-id', name: 'The greatest workspace...pause...in the world' },
|
|
48
|
+
{ type: 'document', groupId: 'some-document-id', name: 'Ricky\'s grade 10 word papers' },
|
|
49
|
+
{ type: 'document', groupId: 'another-document-id', name: 'Sunnyvale bylaws' }
|
|
50
50
|
];
|
|
51
51
|
|
|
52
52
|
// If your product has the concept of user roles (admin, guest, member, etc), provide it here
|
|
@@ -122,7 +122,7 @@ function InviteWrapperComponent() {
|
|
|
122
122
|
return (<VortexInvite
|
|
123
123
|
widgetId={widgetId}
|
|
124
124
|
jwt={jwt}
|
|
125
|
-
group={{
|
|
125
|
+
group={{ type: "workspace", groupId: "some-workspace-id", name: "The greatest workspace...pause...in the world" }}
|
|
126
126
|
templateVariables={{
|
|
127
127
|
group_name: "The greatest workspace...pause...in the world",
|
|
128
128
|
inviter_name: "James Lahey",
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
type InvitationTarget = {
|
|
2
|
+
type: 'email' | 'sms';
|
|
3
|
+
value: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* GroupInput is used when creating JWTs - represents customer's group data
|
|
7
|
+
* Supports both 'id' (legacy) and 'group_id' (preferred) for backward compatibility
|
|
8
|
+
*/
|
|
9
|
+
type GroupInput = {
|
|
10
|
+
type: string;
|
|
11
|
+
id?: string;
|
|
12
|
+
groupId?: string;
|
|
13
|
+
name: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* InvitationGroup represents a group in API responses
|
|
17
|
+
* This matches the MemberGroups table structure from the API
|
|
18
|
+
*/
|
|
19
|
+
type InvitationGroup = {
|
|
20
|
+
id: string;
|
|
21
|
+
accountId: string;
|
|
22
|
+
groupId: string;
|
|
23
|
+
type: string;
|
|
24
|
+
name: string;
|
|
25
|
+
createdAt: string;
|
|
26
|
+
};
|
|
27
|
+
type InvitationAcceptance = {
|
|
28
|
+
id: string;
|
|
29
|
+
accountId: string;
|
|
30
|
+
projectId: string;
|
|
31
|
+
acceptedAt: string;
|
|
32
|
+
target: InvitationTarget;
|
|
33
|
+
};
|
|
34
|
+
type InvitationResult = {
|
|
35
|
+
id: string;
|
|
36
|
+
accountId: string;
|
|
37
|
+
clickThroughs: number;
|
|
38
|
+
configurationAttributes: Record<string, any> | null;
|
|
39
|
+
attributes: Record<string, any> | null;
|
|
40
|
+
createdAt: string;
|
|
41
|
+
deactivated: boolean;
|
|
42
|
+
deliveryCount: number;
|
|
43
|
+
deliveryTypes: ('email' | 'sms' | 'share')[];
|
|
44
|
+
foreignCreatorId: string;
|
|
45
|
+
invitationType: 'single_use' | 'multi_use';
|
|
46
|
+
modifiedAt: string | null;
|
|
47
|
+
status: 'queued' | 'sending' | 'delivered' | 'accepted' | 'shared' | 'unfurled' | 'accepted_elsewhere';
|
|
48
|
+
target: InvitationTarget[];
|
|
49
|
+
views: number;
|
|
50
|
+
widgetConfigurationId: string;
|
|
51
|
+
projectId: string;
|
|
52
|
+
groups: InvitationGroup[];
|
|
53
|
+
accepts: InvitationAcceptance[];
|
|
54
|
+
};
|
|
55
|
+
type AcceptInvitationRequest = {
|
|
56
|
+
invitationIds: string[];
|
|
57
|
+
target: InvitationTarget;
|
|
58
|
+
};
|
|
59
|
+
type ApiResponseJson = InvitationResult | {
|
|
60
|
+
invitations: InvitationResult[];
|
|
61
|
+
} | {};
|
|
62
|
+
type ApiRequestBody = AcceptInvitationRequest | null;
|
|
63
|
+
|
|
64
|
+
declare class Vortex {
|
|
65
|
+
private apiKey;
|
|
66
|
+
constructor(apiKey: string);
|
|
67
|
+
generateJwt({ userId, identifiers, groups, role, attributes, }: {
|
|
68
|
+
userId: string;
|
|
69
|
+
identifiers: {
|
|
70
|
+
type: 'email' | 'sms';
|
|
71
|
+
value: string;
|
|
72
|
+
}[];
|
|
73
|
+
groups: GroupInput[];
|
|
74
|
+
role?: string;
|
|
75
|
+
attributes?: Record<string, any>;
|
|
76
|
+
}): string;
|
|
77
|
+
vortexApiRequest(options: {
|
|
78
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
79
|
+
path: string;
|
|
80
|
+
body?: ApiRequestBody;
|
|
81
|
+
queryParams?: Record<string, string | number | boolean>;
|
|
82
|
+
}): Promise<ApiResponseJson>;
|
|
83
|
+
getInvitationsByTarget(targetType: 'email' | 'username' | 'phoneNumber', targetValue: string): Promise<InvitationResult[]>;
|
|
84
|
+
getInvitation(invitationId: string): Promise<InvitationResult>;
|
|
85
|
+
revokeInvitation(invitationId: string): Promise<{}>;
|
|
86
|
+
acceptInvitations(invitationIds: string[], target: {
|
|
87
|
+
type: 'email' | 'username' | 'phoneNumber';
|
|
88
|
+
value: string;
|
|
89
|
+
}): Promise<InvitationResult>;
|
|
90
|
+
deleteInvitationsByGroup(groupType: string, groupId: string): Promise<{}>;
|
|
91
|
+
getInvitationsByGroup(groupType: string, groupId: string): Promise<InvitationResult[]>;
|
|
92
|
+
reinvite(invitationId: string): Promise<InvitationResult>;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export { type AcceptInvitationRequest, type ApiRequestBody, type ApiResponseJson, type GroupInput, type InvitationAcceptance, type InvitationGroup, type InvitationResult, type InvitationTarget, Vortex };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,95 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
type InvitationTarget = {
|
|
2
|
+
type: 'email' | 'sms';
|
|
3
|
+
value: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* GroupInput is used when creating JWTs - represents customer's group data
|
|
7
|
+
* Supports both 'id' (legacy) and 'group_id' (preferred) for backward compatibility
|
|
8
|
+
*/
|
|
9
|
+
type GroupInput = {
|
|
10
|
+
type: string;
|
|
11
|
+
id?: string;
|
|
12
|
+
groupId?: string;
|
|
13
|
+
name: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* InvitationGroup represents a group in API responses
|
|
17
|
+
* This matches the MemberGroups table structure from the API
|
|
18
|
+
*/
|
|
19
|
+
type InvitationGroup = {
|
|
20
|
+
id: string;
|
|
21
|
+
accountId: string;
|
|
22
|
+
groupId: string;
|
|
23
|
+
type: string;
|
|
24
|
+
name: string;
|
|
25
|
+
createdAt: string;
|
|
26
|
+
};
|
|
27
|
+
type InvitationAcceptance = {
|
|
28
|
+
id: string;
|
|
29
|
+
accountId: string;
|
|
30
|
+
projectId: string;
|
|
31
|
+
acceptedAt: string;
|
|
32
|
+
target: InvitationTarget;
|
|
33
|
+
};
|
|
34
|
+
type InvitationResult = {
|
|
35
|
+
id: string;
|
|
36
|
+
accountId: string;
|
|
37
|
+
clickThroughs: number;
|
|
38
|
+
configurationAttributes: Record<string, any> | null;
|
|
39
|
+
attributes: Record<string, any> | null;
|
|
40
|
+
createdAt: string;
|
|
41
|
+
deactivated: boolean;
|
|
42
|
+
deliveryCount: number;
|
|
43
|
+
deliveryTypes: ('email' | 'sms' | 'share')[];
|
|
44
|
+
foreignCreatorId: string;
|
|
45
|
+
invitationType: 'single_use' | 'multi_use';
|
|
46
|
+
modifiedAt: string | null;
|
|
47
|
+
status: 'queued' | 'sending' | 'delivered' | 'accepted' | 'shared' | 'unfurled' | 'accepted_elsewhere';
|
|
48
|
+
target: InvitationTarget[];
|
|
49
|
+
views: number;
|
|
50
|
+
widgetConfigurationId: string;
|
|
51
|
+
projectId: string;
|
|
52
|
+
groups: InvitationGroup[];
|
|
53
|
+
accepts: InvitationAcceptance[];
|
|
54
|
+
};
|
|
55
|
+
type AcceptInvitationRequest = {
|
|
56
|
+
invitationIds: string[];
|
|
57
|
+
target: InvitationTarget;
|
|
58
|
+
};
|
|
59
|
+
type ApiResponseJson = InvitationResult | {
|
|
60
|
+
invitations: InvitationResult[];
|
|
61
|
+
} | {};
|
|
62
|
+
type ApiRequestBody = AcceptInvitationRequest | null;
|
|
63
|
+
|
|
64
|
+
declare class Vortex {
|
|
65
|
+
private apiKey;
|
|
66
|
+
constructor(apiKey: string);
|
|
67
|
+
generateJwt({ userId, identifiers, groups, role, attributes, }: {
|
|
68
|
+
userId: string;
|
|
69
|
+
identifiers: {
|
|
70
|
+
type: 'email' | 'sms';
|
|
71
|
+
value: string;
|
|
72
|
+
}[];
|
|
73
|
+
groups: GroupInput[];
|
|
74
|
+
role?: string;
|
|
75
|
+
attributes?: Record<string, any>;
|
|
76
|
+
}): string;
|
|
77
|
+
vortexApiRequest(options: {
|
|
78
|
+
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
79
|
+
path: string;
|
|
80
|
+
body?: ApiRequestBody;
|
|
81
|
+
queryParams?: Record<string, string | number | boolean>;
|
|
82
|
+
}): Promise<ApiResponseJson>;
|
|
83
|
+
getInvitationsByTarget(targetType: 'email' | 'username' | 'phoneNumber', targetValue: string): Promise<InvitationResult[]>;
|
|
84
|
+
getInvitation(invitationId: string): Promise<InvitationResult>;
|
|
85
|
+
revokeInvitation(invitationId: string): Promise<{}>;
|
|
86
|
+
acceptInvitations(invitationIds: string[], target: {
|
|
87
|
+
type: 'email' | 'username' | 'phoneNumber';
|
|
88
|
+
value: string;
|
|
89
|
+
}): Promise<InvitationResult>;
|
|
90
|
+
deleteInvitationsByGroup(groupType: string, groupId: string): Promise<{}>;
|
|
91
|
+
getInvitationsByGroup(groupType: string, groupId: string): Promise<InvitationResult[]>;
|
|
92
|
+
reinvite(invitationId: string): Promise<InvitationResult>;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export { type AcceptInvitationRequest, type ApiRequestBody, type ApiResponseJson, type GroupInput, type InvitationAcceptance, type InvitationGroup, type InvitationResult, type InvitationTarget, Vortex };
|
package/dist/index.js
CHANGED
|
@@ -1,18 +1,177 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
Vortex: () => Vortex
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
|
|
37
|
+
// src/vortex.ts
|
|
38
|
+
var import_node_crypto = __toESM(require("crypto"));
|
|
39
|
+
var import_uuid = require("uuid");
|
|
40
|
+
var Vortex = class {
|
|
41
|
+
constructor(apiKey) {
|
|
42
|
+
this.apiKey = apiKey;
|
|
43
|
+
}
|
|
44
|
+
generateJwt({
|
|
45
|
+
userId,
|
|
46
|
+
identifiers,
|
|
47
|
+
groups,
|
|
48
|
+
role,
|
|
49
|
+
attributes
|
|
50
|
+
}) {
|
|
51
|
+
const [prefix, encodedId, key] = this.apiKey.split(".");
|
|
52
|
+
if (!prefix || !encodedId || !key) {
|
|
53
|
+
throw new Error("Invalid API key format");
|
|
54
|
+
}
|
|
55
|
+
if (prefix !== "VRTX") {
|
|
56
|
+
throw new Error("Invalid API key prefix");
|
|
57
|
+
}
|
|
58
|
+
const id = (0, import_uuid.stringify)(Buffer.from(encodedId, "base64url"));
|
|
59
|
+
const expires = Math.floor(Date.now() / 1e3) + 3600;
|
|
60
|
+
const signingKey = import_node_crypto.default.createHmac("sha256", key).update(id).digest();
|
|
61
|
+
const header = {
|
|
62
|
+
iat: Math.floor(Date.now() / 1e3),
|
|
63
|
+
alg: "HS256",
|
|
64
|
+
typ: "JWT",
|
|
65
|
+
kid: id
|
|
66
|
+
};
|
|
67
|
+
const payload = {
|
|
68
|
+
userId,
|
|
69
|
+
groups,
|
|
70
|
+
role,
|
|
71
|
+
expires,
|
|
72
|
+
identifiers,
|
|
73
|
+
...attributes && Object.keys(attributes).length > 0 ? { attributes } : {}
|
|
74
|
+
};
|
|
75
|
+
const headerB64 = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
76
|
+
const payloadB64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
77
|
+
const toSign = `${headerB64}.${payloadB64}`;
|
|
78
|
+
const signature = Buffer.from(
|
|
79
|
+
import_node_crypto.default.createHmac("sha256", signingKey).update(toSign).digest()
|
|
80
|
+
).toString("base64url");
|
|
81
|
+
const jwt = `${toSign}.${signature}`;
|
|
82
|
+
return jwt;
|
|
83
|
+
}
|
|
84
|
+
async vortexApiRequest(options) {
|
|
85
|
+
const { method, path, body, queryParams } = options;
|
|
86
|
+
const url = new URL(`${process.env.VORTEX_API_BASE_URL || "https://api.vortexsoftware.com"}${path}`);
|
|
87
|
+
if (queryParams) {
|
|
88
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
89
|
+
url.searchParams.append(key, String(value));
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
const results = await fetch(url.toString(), {
|
|
93
|
+
method,
|
|
94
|
+
headers: {
|
|
95
|
+
"Content-Type": "application/json",
|
|
96
|
+
"x-api-key": this.apiKey
|
|
97
|
+
},
|
|
98
|
+
body: body ? JSON.stringify(body) : void 0
|
|
99
|
+
});
|
|
100
|
+
if (!results.ok) {
|
|
101
|
+
const errorBody = await results.text();
|
|
102
|
+
throw new Error(`Vortex API request failed: ${results.status} ${results.statusText} - ${errorBody}`);
|
|
103
|
+
}
|
|
104
|
+
const contentLength = results.headers.get("content-length");
|
|
105
|
+
const contentType = results.headers.get("content-type");
|
|
106
|
+
if (contentLength === "0" || !(contentType == null ? void 0 : contentType.includes("application/json")) && !contentLength) {
|
|
107
|
+
return {};
|
|
108
|
+
}
|
|
109
|
+
const responseText = await results.text();
|
|
110
|
+
if (!responseText.trim()) {
|
|
111
|
+
return {};
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
return JSON.parse(responseText);
|
|
115
|
+
} catch (error) {
|
|
116
|
+
return {};
|
|
7
117
|
}
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
118
|
+
}
|
|
119
|
+
async getInvitationsByTarget(targetType, targetValue) {
|
|
120
|
+
const response = await this.vortexApiRequest({
|
|
121
|
+
method: "GET",
|
|
122
|
+
path: "/api/v1/invitations?targetType",
|
|
123
|
+
queryParams: {
|
|
124
|
+
targetType,
|
|
125
|
+
targetValue
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
return response.invitations;
|
|
129
|
+
}
|
|
130
|
+
async getInvitation(invitationId) {
|
|
131
|
+
return this.vortexApiRequest({
|
|
132
|
+
method: "GET",
|
|
133
|
+
path: `/api/v1/invitations/${invitationId}`
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
async revokeInvitation(invitationId) {
|
|
137
|
+
return this.vortexApiRequest({
|
|
138
|
+
method: "DELETE",
|
|
139
|
+
path: `/api/v1/invitations/${invitationId}`
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
async acceptInvitations(invitationIds, target) {
|
|
143
|
+
const response = await this.vortexApiRequest({
|
|
144
|
+
method: "POST",
|
|
145
|
+
body: {
|
|
146
|
+
invitationIds,
|
|
147
|
+
target
|
|
148
|
+
},
|
|
149
|
+
path: `/api/v1/invitations/accept`
|
|
150
|
+
});
|
|
151
|
+
return response;
|
|
152
|
+
}
|
|
153
|
+
async deleteInvitationsByGroup(groupType, groupId) {
|
|
154
|
+
return this.vortexApiRequest({
|
|
155
|
+
method: "DELETE",
|
|
156
|
+
path: `/api/v1/invitations/by-group/${groupType}/${groupId}`
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
async getInvitationsByGroup(groupType, groupId) {
|
|
160
|
+
const response = await this.vortexApiRequest({
|
|
161
|
+
method: "GET",
|
|
162
|
+
path: `/api/v1/invitations/by-group/${groupType}/${groupId}`
|
|
163
|
+
});
|
|
164
|
+
return response.invitations;
|
|
165
|
+
}
|
|
166
|
+
async reinvite(invitationId) {
|
|
167
|
+
return this.vortexApiRequest({
|
|
168
|
+
method: "POST",
|
|
169
|
+
path: `/api/v1/invitations/${invitationId}/reinvite`
|
|
170
|
+
});
|
|
171
|
+
}
|
|
15
172
|
};
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
173
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
174
|
+
0 && (module.exports = {
|
|
175
|
+
Vortex
|
|
176
|
+
});
|
|
177
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/vortex.ts"],"sourcesContent":["export * from './vortex';\nexport * from './types';","import crypto from 'node:crypto';\nimport { stringify as uuidStringify } from 'uuid';\nimport { ApiRequestBody, ApiResponseJson, InvitationResult, AcceptInvitationRequest, GroupInput } from './types';\n\nexport class Vortex {\n constructor(private apiKey: string) { }\n\n generateJwt({\n userId,\n identifiers,\n groups,\n role,\n attributes,\n }: {\n userId: string;\n identifiers: { type: 'email' | 'sms'; value: string }[];\n groups: GroupInput[];\n role?: string;\n attributes?: Record<string, any>;\n }): string {\n const [prefix, encodedId, key] = this.apiKey.split('.'); // prefix is just VRTX\n if (!prefix || !encodedId || !key) {\n throw new Error('Invalid API key format');\n }\n if (prefix !== 'VRTX') {\n throw new Error('Invalid API key prefix');\n }\n const id = uuidStringify(Buffer.from(encodedId, 'base64url'));\n\n const expires = Math.floor(Date.now() / 1000) + 3600;\n\n // 🔐 Step 1: Derive signing key from API key + ID\n const signingKey = crypto.createHmac('sha256', key).update(id).digest(); // <- raw Buffer\n\n // 🧱 Step 2: Build header + payload\n const header = {\n iat: Math.floor(Date.now() / 1000),\n alg: 'HS256',\n typ: 'JWT',\n kid: id,\n };\n\n const payload = {\n userId,\n groups,\n role,\n expires,\n identifiers,\n ...(attributes && Object.keys(attributes).length > 0 ? { attributes } : {}),\n };\n\n // 🧱 Step 3: Base64URL encode\n const headerB64 = Buffer.from(JSON.stringify(header)).toString('base64url');\n const payloadB64 = Buffer.from(JSON.stringify(payload)).toString('base64url');\n\n // 🧾 Step 4: Sign\n const toSign = `${headerB64}.${payloadB64}`;\n const signature = Buffer.from(\n crypto.createHmac('sha256', signingKey).update(toSign).digest()\n ).toString('base64url');\n const jwt = `${toSign}.${signature}`;\n return jwt;\n }\n\n async vortexApiRequest(options: {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE',\n path: string,\n body?: ApiRequestBody,\n queryParams?: Record<string, string | number | boolean>,\n }): Promise<ApiResponseJson> {\n const { method, path, body, queryParams } = options;\n const url = new URL(`${process.env.VORTEX_API_BASE_URL || 'https://api.vortexsoftware.com'}${path}`);\n if (queryParams) {\n Object.entries(queryParams).forEach(([key, value]) => {\n url.searchParams.append(key, String(value));\n });\n }\n const results = await fetch(url.toString(), {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n },\n body: body ? JSON.stringify(body) : undefined,\n });\n if (!results.ok) {\n const errorBody = await results.text();\n throw new Error(`Vortex API request failed: ${results.status} ${results.statusText} - ${errorBody}`);\n }\n\n // Check if response has content to parse\n const contentLength = results.headers.get('content-length');\n const contentType = results.headers.get('content-type');\n\n // If no content or content-length is 0, return empty object\n if (contentLength === '0' || (!contentType?.includes('application/json') && !contentLength)) {\n return {};\n }\n\n // Try to get text first to check if there's actually content\n const responseText = await results.text();\n if (!responseText.trim()) {\n return {};\n }\n\n // Parse JSON if there's content\n try {\n return JSON.parse(responseText);\n } catch (error) {\n // If JSON parsing fails, return the text or empty object\n return {};\n }\n }\n\n async getInvitationsByTarget(targetType: 'email' | 'username' | 'phoneNumber', targetValue: string): Promise<InvitationResult[]> {\n const response = await this.vortexApiRequest({\n method: 'GET',\n path: '/api/v1/invitations?targetType',\n queryParams: {\n targetType,\n targetValue,\n }\n }) as { invitations: InvitationResult[] };\n return response.invitations;\n }\n\n async getInvitation(invitationId: string): Promise<InvitationResult> {\n return this.vortexApiRequest({\n method: 'GET',\n path: `/api/v1/invitations/${invitationId}`,\n }) as Promise<InvitationResult>;\n }\n\n async revokeInvitation(invitationId: string): Promise<{}> {\n return this.vortexApiRequest({\n method: 'DELETE',\n path: `/api/v1/invitations/${invitationId}`,\n }) as Promise<{}>;\n }\n\n async acceptInvitations(\n invitationIds: string[],\n target: { type: 'email' | 'username' | 'phoneNumber'; value: string }\n ): Promise<InvitationResult> {\n const response = await this.vortexApiRequest({\n method: 'POST',\n body: {\n invitationIds,\n target,\n } as AcceptInvitationRequest,\n path: `/api/v1/invitations/accept`,\n }) as InvitationResult;\n return response;\n }\n\n async deleteInvitationsByGroup(groupType: string, groupId: string): Promise<{}> {\n return this.vortexApiRequest({\n method: 'DELETE',\n path: `/api/v1/invitations/by-group/${groupType}/${groupId}`,\n }) as Promise<{}>;\n }\n\n async getInvitationsByGroup(groupType: string, groupId: string): Promise<InvitationResult[]> {\n const response = await this.vortexApiRequest({\n method: 'GET',\n path: `/api/v1/invitations/by-group/${groupType}/${groupId}`,\n }) as { invitations: InvitationResult[] };\n return response.invitations;\n }\n\n async reinvite(invitationId: string): Promise<InvitationResult> {\n return this.vortexApiRequest({\n method: 'POST',\n path: `/api/v1/invitations/${invitationId}/reinvite`,\n }) as Promise<InvitationResult>;\n }\n}"],"mappings":"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","names":["uuidStringify","crypto"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
// src/vortex.ts
|
|
2
|
+
import crypto from "crypto";
|
|
3
|
+
import { stringify as uuidStringify } from "uuid";
|
|
4
|
+
var Vortex = class {
|
|
5
|
+
constructor(apiKey) {
|
|
6
|
+
this.apiKey = apiKey;
|
|
7
|
+
}
|
|
8
|
+
generateJwt({
|
|
9
|
+
userId,
|
|
10
|
+
identifiers,
|
|
11
|
+
groups,
|
|
12
|
+
role,
|
|
13
|
+
attributes
|
|
14
|
+
}) {
|
|
15
|
+
const [prefix, encodedId, key] = this.apiKey.split(".");
|
|
16
|
+
if (!prefix || !encodedId || !key) {
|
|
17
|
+
throw new Error("Invalid API key format");
|
|
18
|
+
}
|
|
19
|
+
if (prefix !== "VRTX") {
|
|
20
|
+
throw new Error("Invalid API key prefix");
|
|
21
|
+
}
|
|
22
|
+
const id = uuidStringify(Buffer.from(encodedId, "base64url"));
|
|
23
|
+
const expires = Math.floor(Date.now() / 1e3) + 3600;
|
|
24
|
+
const signingKey = crypto.createHmac("sha256", key).update(id).digest();
|
|
25
|
+
const header = {
|
|
26
|
+
iat: Math.floor(Date.now() / 1e3),
|
|
27
|
+
alg: "HS256",
|
|
28
|
+
typ: "JWT",
|
|
29
|
+
kid: id
|
|
30
|
+
};
|
|
31
|
+
const payload = {
|
|
32
|
+
userId,
|
|
33
|
+
groups,
|
|
34
|
+
role,
|
|
35
|
+
expires,
|
|
36
|
+
identifiers,
|
|
37
|
+
...attributes && Object.keys(attributes).length > 0 ? { attributes } : {}
|
|
38
|
+
};
|
|
39
|
+
const headerB64 = Buffer.from(JSON.stringify(header)).toString("base64url");
|
|
40
|
+
const payloadB64 = Buffer.from(JSON.stringify(payload)).toString("base64url");
|
|
41
|
+
const toSign = `${headerB64}.${payloadB64}`;
|
|
42
|
+
const signature = Buffer.from(
|
|
43
|
+
crypto.createHmac("sha256", signingKey).update(toSign).digest()
|
|
44
|
+
).toString("base64url");
|
|
45
|
+
const jwt = `${toSign}.${signature}`;
|
|
46
|
+
return jwt;
|
|
47
|
+
}
|
|
48
|
+
async vortexApiRequest(options) {
|
|
49
|
+
const { method, path, body, queryParams } = options;
|
|
50
|
+
const url = new URL(`${process.env.VORTEX_API_BASE_URL || "https://api.vortexsoftware.com"}${path}`);
|
|
51
|
+
if (queryParams) {
|
|
52
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
53
|
+
url.searchParams.append(key, String(value));
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
const results = await fetch(url.toString(), {
|
|
57
|
+
method,
|
|
58
|
+
headers: {
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
"x-api-key": this.apiKey
|
|
61
|
+
},
|
|
62
|
+
body: body ? JSON.stringify(body) : void 0
|
|
63
|
+
});
|
|
64
|
+
if (!results.ok) {
|
|
65
|
+
const errorBody = await results.text();
|
|
66
|
+
throw new Error(`Vortex API request failed: ${results.status} ${results.statusText} - ${errorBody}`);
|
|
67
|
+
}
|
|
68
|
+
const contentLength = results.headers.get("content-length");
|
|
69
|
+
const contentType = results.headers.get("content-type");
|
|
70
|
+
if (contentLength === "0" || !(contentType == null ? void 0 : contentType.includes("application/json")) && !contentLength) {
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
73
|
+
const responseText = await results.text();
|
|
74
|
+
if (!responseText.trim()) {
|
|
75
|
+
return {};
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
return JSON.parse(responseText);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
async getInvitationsByTarget(targetType, targetValue) {
|
|
84
|
+
const response = await this.vortexApiRequest({
|
|
85
|
+
method: "GET",
|
|
86
|
+
path: "/api/v1/invitations?targetType",
|
|
87
|
+
queryParams: {
|
|
88
|
+
targetType,
|
|
89
|
+
targetValue
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
return response.invitations;
|
|
93
|
+
}
|
|
94
|
+
async getInvitation(invitationId) {
|
|
95
|
+
return this.vortexApiRequest({
|
|
96
|
+
method: "GET",
|
|
97
|
+
path: `/api/v1/invitations/${invitationId}`
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async revokeInvitation(invitationId) {
|
|
101
|
+
return this.vortexApiRequest({
|
|
102
|
+
method: "DELETE",
|
|
103
|
+
path: `/api/v1/invitations/${invitationId}`
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async acceptInvitations(invitationIds, target) {
|
|
107
|
+
const response = await this.vortexApiRequest({
|
|
108
|
+
method: "POST",
|
|
109
|
+
body: {
|
|
110
|
+
invitationIds,
|
|
111
|
+
target
|
|
112
|
+
},
|
|
113
|
+
path: `/api/v1/invitations/accept`
|
|
114
|
+
});
|
|
115
|
+
return response;
|
|
116
|
+
}
|
|
117
|
+
async deleteInvitationsByGroup(groupType, groupId) {
|
|
118
|
+
return this.vortexApiRequest({
|
|
119
|
+
method: "DELETE",
|
|
120
|
+
path: `/api/v1/invitations/by-group/${groupType}/${groupId}`
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
async getInvitationsByGroup(groupType, groupId) {
|
|
124
|
+
const response = await this.vortexApiRequest({
|
|
125
|
+
method: "GET",
|
|
126
|
+
path: `/api/v1/invitations/by-group/${groupType}/${groupId}`
|
|
127
|
+
});
|
|
128
|
+
return response.invitations;
|
|
129
|
+
}
|
|
130
|
+
async reinvite(invitationId) {
|
|
131
|
+
return this.vortexApiRequest({
|
|
132
|
+
method: "POST",
|
|
133
|
+
path: `/api/v1/invitations/${invitationId}/reinvite`
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
export {
|
|
138
|
+
Vortex
|
|
139
|
+
};
|
|
140
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/vortex.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport { stringify as uuidStringify } from 'uuid';\nimport { ApiRequestBody, ApiResponseJson, InvitationResult, AcceptInvitationRequest, GroupInput } from './types';\n\nexport class Vortex {\n constructor(private apiKey: string) { }\n\n generateJwt({\n userId,\n identifiers,\n groups,\n role,\n attributes,\n }: {\n userId: string;\n identifiers: { type: 'email' | 'sms'; value: string }[];\n groups: GroupInput[];\n role?: string;\n attributes?: Record<string, any>;\n }): string {\n const [prefix, encodedId, key] = this.apiKey.split('.'); // prefix is just VRTX\n if (!prefix || !encodedId || !key) {\n throw new Error('Invalid API key format');\n }\n if (prefix !== 'VRTX') {\n throw new Error('Invalid API key prefix');\n }\n const id = uuidStringify(Buffer.from(encodedId, 'base64url'));\n\n const expires = Math.floor(Date.now() / 1000) + 3600;\n\n // 🔐 Step 1: Derive signing key from API key + ID\n const signingKey = crypto.createHmac('sha256', key).update(id).digest(); // <- raw Buffer\n\n // 🧱 Step 2: Build header + payload\n const header = {\n iat: Math.floor(Date.now() / 1000),\n alg: 'HS256',\n typ: 'JWT',\n kid: id,\n };\n\n const payload = {\n userId,\n groups,\n role,\n expires,\n identifiers,\n ...(attributes && Object.keys(attributes).length > 0 ? { attributes } : {}),\n };\n\n // 🧱 Step 3: Base64URL encode\n const headerB64 = Buffer.from(JSON.stringify(header)).toString('base64url');\n const payloadB64 = Buffer.from(JSON.stringify(payload)).toString('base64url');\n\n // 🧾 Step 4: Sign\n const toSign = `${headerB64}.${payloadB64}`;\n const signature = Buffer.from(\n crypto.createHmac('sha256', signingKey).update(toSign).digest()\n ).toString('base64url');\n const jwt = `${toSign}.${signature}`;\n return jwt;\n }\n\n async vortexApiRequest(options: {\n method: 'GET' | 'POST' | 'PUT' | 'DELETE',\n path: string,\n body?: ApiRequestBody,\n queryParams?: Record<string, string | number | boolean>,\n }): Promise<ApiResponseJson> {\n const { method, path, body, queryParams } = options;\n const url = new URL(`${process.env.VORTEX_API_BASE_URL || 'https://api.vortexsoftware.com'}${path}`);\n if (queryParams) {\n Object.entries(queryParams).forEach(([key, value]) => {\n url.searchParams.append(key, String(value));\n });\n }\n const results = await fetch(url.toString(), {\n method,\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey,\n },\n body: body ? JSON.stringify(body) : undefined,\n });\n if (!results.ok) {\n const errorBody = await results.text();\n throw new Error(`Vortex API request failed: ${results.status} ${results.statusText} - ${errorBody}`);\n }\n\n // Check if response has content to parse\n const contentLength = results.headers.get('content-length');\n const contentType = results.headers.get('content-type');\n\n // If no content or content-length is 0, return empty object\n if (contentLength === '0' || (!contentType?.includes('application/json') && !contentLength)) {\n return {};\n }\n\n // Try to get text first to check if there's actually content\n const responseText = await results.text();\n if (!responseText.trim()) {\n return {};\n }\n\n // Parse JSON if there's content\n try {\n return JSON.parse(responseText);\n } catch (error) {\n // If JSON parsing fails, return the text or empty object\n return {};\n }\n }\n\n async getInvitationsByTarget(targetType: 'email' | 'username' | 'phoneNumber', targetValue: string): Promise<InvitationResult[]> {\n const response = await this.vortexApiRequest({\n method: 'GET',\n path: '/api/v1/invitations?targetType',\n queryParams: {\n targetType,\n targetValue,\n }\n }) as { invitations: InvitationResult[] };\n return response.invitations;\n }\n\n async getInvitation(invitationId: string): Promise<InvitationResult> {\n return this.vortexApiRequest({\n method: 'GET',\n path: `/api/v1/invitations/${invitationId}`,\n }) as Promise<InvitationResult>;\n }\n\n async revokeInvitation(invitationId: string): Promise<{}> {\n return this.vortexApiRequest({\n method: 'DELETE',\n path: `/api/v1/invitations/${invitationId}`,\n }) as Promise<{}>;\n }\n\n async acceptInvitations(\n invitationIds: string[],\n target: { type: 'email' | 'username' | 'phoneNumber'; value: string }\n ): Promise<InvitationResult> {\n const response = await this.vortexApiRequest({\n method: 'POST',\n body: {\n invitationIds,\n target,\n } as AcceptInvitationRequest,\n path: `/api/v1/invitations/accept`,\n }) as InvitationResult;\n return response;\n }\n\n async deleteInvitationsByGroup(groupType: string, groupId: string): Promise<{}> {\n return this.vortexApiRequest({\n method: 'DELETE',\n path: `/api/v1/invitations/by-group/${groupType}/${groupId}`,\n }) as Promise<{}>;\n }\n\n async getInvitationsByGroup(groupType: string, groupId: string): Promise<InvitationResult[]> {\n const response = await this.vortexApiRequest({\n method: 'GET',\n path: `/api/v1/invitations/by-group/${groupType}/${groupId}`,\n }) as { invitations: InvitationResult[] };\n return response.invitations;\n }\n\n async reinvite(invitationId: string): Promise<InvitationResult> {\n return this.vortexApiRequest({\n method: 'POST',\n path: `/api/v1/invitations/${invitationId}/reinvite`,\n }) as Promise<InvitationResult>;\n }\n}"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
"name": "@teamvortexsoftware/vortex-node-22-sdk",
|
|
3
3
|
"description": "Vortex Node 22 SDK",
|
|
4
4
|
"author": "@teamvortexsoftware",
|
|
5
|
-
"version": "0.0.
|
|
6
|
-
"main": "./dist/
|
|
7
|
-
"module": "./dist/
|
|
8
|
-
"types": "./dist/
|
|
5
|
+
"version": "0.0.5",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.mjs",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"
|
|
12
|
-
"
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.mjs",
|
|
13
|
+
"require": "./dist/index.js"
|
|
13
14
|
}
|
|
14
15
|
},
|
|
15
16
|
"files": [
|
|
@@ -28,7 +29,7 @@
|
|
|
28
29
|
"dev": "",
|
|
29
30
|
"test": "jest",
|
|
30
31
|
"package": "pnpm run build && cd dist/vortex-node-22-sdk && npm pack",
|
|
31
|
-
"build": "
|
|
32
|
+
"build": "tsup"
|
|
32
33
|
},
|
|
33
34
|
"jest": {
|
|
34
35
|
"rootDir": "__tests__",
|
|
@@ -49,6 +50,7 @@
|
|
|
49
50
|
"@teamvortexsoftware/typescript-config": "workspace:*",
|
|
50
51
|
"eslint": "^9.24.0",
|
|
51
52
|
"jest": "29.7.0",
|
|
53
|
+
"tsup": "^8.5.0",
|
|
52
54
|
"typescript-eslint": "^8.30.1"
|
|
53
55
|
},
|
|
54
56
|
"dependencies": {
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,cAAc,SAAS,CAAC"}
|
package/dist/types.d.ts
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
export type InvitationTarget = {
|
|
2
|
-
type: 'email' | 'sms';
|
|
3
|
-
value: string;
|
|
4
|
-
};
|
|
5
|
-
export type InvitationGroup = {
|
|
6
|
-
id: string;
|
|
7
|
-
type: string;
|
|
8
|
-
name: string;
|
|
9
|
-
};
|
|
10
|
-
export type InvitationAcceptance = {
|
|
11
|
-
id: string;
|
|
12
|
-
accountId: string;
|
|
13
|
-
projectId: string;
|
|
14
|
-
acceptedAt: string;
|
|
15
|
-
target: InvitationTarget;
|
|
16
|
-
};
|
|
17
|
-
export type InvitationResult = {
|
|
18
|
-
id: string;
|
|
19
|
-
accountId: string;
|
|
20
|
-
clickThroughs: number;
|
|
21
|
-
configurationAttributes: Record<string, any> | null;
|
|
22
|
-
attributes: Record<string, any> | null;
|
|
23
|
-
createdAt: string;
|
|
24
|
-
deactivated: boolean;
|
|
25
|
-
deliveryCount: number;
|
|
26
|
-
deliveryTypes: ('email' | 'sms' | 'share')[];
|
|
27
|
-
foreignCreatorId: string;
|
|
28
|
-
invitationType: 'single_use' | 'multi_use';
|
|
29
|
-
modifiedAt: string | null;
|
|
30
|
-
status: 'queued' | 'sending' | 'delivered' | 'accepted' | 'shared' | 'unfurled' | 'accepted_elsewhere';
|
|
31
|
-
target: InvitationTarget[];
|
|
32
|
-
views: number;
|
|
33
|
-
widgetConfigurationId: string;
|
|
34
|
-
projectId: string;
|
|
35
|
-
groups: InvitationGroup[];
|
|
36
|
-
accepts: InvitationAcceptance[];
|
|
37
|
-
};
|
|
38
|
-
export type AcceptInvitationRequest = {
|
|
39
|
-
invitationIds: string[];
|
|
40
|
-
target: InvitationTarget;
|
|
41
|
-
};
|
|
42
|
-
export type ApiResponseJson = InvitationResult | {
|
|
43
|
-
invitations: InvitationResult[];
|
|
44
|
-
} | {};
|
|
45
|
-
export type ApiRequestBody = AcceptInvitationRequest | null;
|
|
46
|
-
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,gBAAgB,CAAC;CAC1B,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACpD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,CAAC,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC;IAC7C,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,YAAY,GAAG,WAAW,CAAC;IAC3C,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,oBAAoB,CAAC;IACvG,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,qBAAqB,EAAE,MAAM,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,MAAM,EAAE,gBAAgB,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG;IAAE,WAAW,EAAE,gBAAgB,EAAE,CAAA;CAAE,GAAG,EAAE,CAAC;AAE1F,MAAM,MAAM,cAAc,GAAG,uBAAuB,GAAG,IAAI,CAAC"}
|
package/dist/types.js
DELETED
package/dist/vortex.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { ApiRequestBody, ApiResponseJson, InvitationResult } from './types';
|
|
2
|
-
export declare class Vortex {
|
|
3
|
-
private apiKey;
|
|
4
|
-
constructor(apiKey: string);
|
|
5
|
-
generateJwt({ userId, identifiers, groups, role, }: {
|
|
6
|
-
userId: string;
|
|
7
|
-
identifiers: {
|
|
8
|
-
type: 'email' | 'sms';
|
|
9
|
-
value: string;
|
|
10
|
-
}[];
|
|
11
|
-
groups: {
|
|
12
|
-
type: string;
|
|
13
|
-
id: string;
|
|
14
|
-
name: string;
|
|
15
|
-
}[];
|
|
16
|
-
role?: string;
|
|
17
|
-
}): string;
|
|
18
|
-
vortexApiRequest(options: {
|
|
19
|
-
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
20
|
-
path: string;
|
|
21
|
-
body?: ApiRequestBody;
|
|
22
|
-
queryParams?: Record<string, string | number | boolean>;
|
|
23
|
-
}): Promise<ApiResponseJson>;
|
|
24
|
-
getInvitationsByTarget(targetType: 'email' | 'username' | 'phoneNumber', targetValue: string): Promise<InvitationResult[]>;
|
|
25
|
-
getInvitation(invitationId: string): Promise<InvitationResult>;
|
|
26
|
-
revokeInvitation(invitationId: string): Promise<{}>;
|
|
27
|
-
acceptInvitations(invitationIds: string[], target: {
|
|
28
|
-
type: 'email' | 'username' | 'phoneNumber';
|
|
29
|
-
value: string;
|
|
30
|
-
}): Promise<InvitationResult>;
|
|
31
|
-
deleteInvitationsByGroup(groupType: string, groupId: string): Promise<{}>;
|
|
32
|
-
getInvitationsByGroup(groupType: string, groupId: string): Promise<InvitationResult[]>;
|
|
33
|
-
reinvite(invitationId: string): Promise<InvitationResult>;
|
|
34
|
-
}
|
|
35
|
-
//# sourceMappingURL=vortex.d.ts.map
|
package/dist/vortex.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vortex.d.ts","sourceRoot":"","sources":["../src/vortex.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,gBAAgB,EAA2B,MAAM,SAAS,CAAC;AAErG,qBAAa,MAAM;IACL,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM;IAElC,WAAW,CAAC,EACV,MAAM,EACN,WAAW,EACX,MAAM,EACN,IAAI,GACL,EAAE;QACD,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE;YAAE,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACxD,MAAM,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACrD,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,GAAG,MAAM;IA4CJ,gBAAgB,CAAC,OAAO,EAAE;QAC9B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;QAC1C,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,cAAc,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;KACzD,GAAG,OAAO,CAAC,eAAe,CAAC;IAuBtB,sBAAsB,CAAC,UAAU,EAAE,OAAO,GAAG,UAAU,GAAG,aAAa,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAY1H,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAO9D,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;IAOnD,iBAAiB,CACrB,aAAa,EAAE,MAAM,EAAE,EACvB,MAAM,EAAE;QAAE,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,aAAa,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GACpE,OAAO,CAAC,gBAAgB,CAAC;IAYtB,wBAAwB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC;IAOzE,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAQtF,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;CAMhE"}
|
package/dist/vortex.js
DELETED
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
12
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
13
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
14
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
15
|
-
function step(op) {
|
|
16
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
17
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
18
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
19
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
20
|
-
switch (op[0]) {
|
|
21
|
-
case 0: case 1: t = op; break;
|
|
22
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
23
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
24
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
25
|
-
default:
|
|
26
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
27
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
28
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
29
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
30
|
-
if (t[2]) _.ops.pop();
|
|
31
|
-
_.trys.pop(); continue;
|
|
32
|
-
}
|
|
33
|
-
op = body.call(thisArg, _);
|
|
34
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
35
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
39
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
40
|
-
};
|
|
41
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
-
exports.Vortex = void 0;
|
|
43
|
-
var node_crypto_1 = __importDefault(require("node:crypto"));
|
|
44
|
-
var uuid_1 = require("uuid");
|
|
45
|
-
var Vortex = /** @class */ (function () {
|
|
46
|
-
function Vortex(apiKey) {
|
|
47
|
-
this.apiKey = apiKey;
|
|
48
|
-
}
|
|
49
|
-
Vortex.prototype.generateJwt = function (_a) {
|
|
50
|
-
var userId = _a.userId, identifiers = _a.identifiers, groups = _a.groups, role = _a.role;
|
|
51
|
-
var _b = this.apiKey.split('.'), prefix = _b[0], encodedId = _b[1], key = _b[2]; // prefix is just VRTX
|
|
52
|
-
if (!prefix || !encodedId || !key) {
|
|
53
|
-
throw new Error('Invalid API key format');
|
|
54
|
-
}
|
|
55
|
-
if (prefix !== 'VRTX') {
|
|
56
|
-
throw new Error('Invalid API key prefix');
|
|
57
|
-
}
|
|
58
|
-
var id = (0, uuid_1.stringify)(Buffer.from(encodedId, 'base64url'));
|
|
59
|
-
var expires = Math.floor(Date.now() / 1000) + 3600;
|
|
60
|
-
// 🔐 Step 1: Derive signing key from API key + ID
|
|
61
|
-
var signingKey = node_crypto_1.default.createHmac('sha256', key).update(id).digest(); // <- raw Buffer
|
|
62
|
-
// 🧱 Step 2: Build header + payload
|
|
63
|
-
var header = {
|
|
64
|
-
iat: Math.floor(Date.now() / 1000),
|
|
65
|
-
alg: 'HS256',
|
|
66
|
-
typ: 'JWT',
|
|
67
|
-
kid: id,
|
|
68
|
-
};
|
|
69
|
-
var payload = {
|
|
70
|
-
userId: userId,
|
|
71
|
-
groups: groups,
|
|
72
|
-
role: role,
|
|
73
|
-
expires: expires,
|
|
74
|
-
identifiers: identifiers,
|
|
75
|
-
};
|
|
76
|
-
// 🧱 Step 3: Base64URL encode
|
|
77
|
-
var headerB64 = Buffer.from(JSON.stringify(header)).toString('base64url');
|
|
78
|
-
var payloadB64 = Buffer.from(JSON.stringify(payload)).toString('base64url');
|
|
79
|
-
// 🧾 Step 4: Sign
|
|
80
|
-
var toSign = "".concat(headerB64, ".").concat(payloadB64);
|
|
81
|
-
var signature = Buffer.from(node_crypto_1.default.createHmac('sha256', signingKey).update(toSign).digest()).toString('base64url');
|
|
82
|
-
var jwt = "".concat(toSign, ".").concat(signature);
|
|
83
|
-
return jwt;
|
|
84
|
-
};
|
|
85
|
-
Vortex.prototype.vortexApiRequest = function (options) {
|
|
86
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
87
|
-
var method, path, body, queryParams, url, results, errorBody;
|
|
88
|
-
return __generator(this, function (_a) {
|
|
89
|
-
switch (_a.label) {
|
|
90
|
-
case 0:
|
|
91
|
-
method = options.method, path = options.path, body = options.body, queryParams = options.queryParams;
|
|
92
|
-
url = new URL("".concat(process.env.VORTEX_API_BASE_URL || 'https://api.vortexsoftware.com').concat(path));
|
|
93
|
-
if (queryParams) {
|
|
94
|
-
Object.entries(queryParams).forEach(function (_a) {
|
|
95
|
-
var key = _a[0], value = _a[1];
|
|
96
|
-
url.searchParams.append(key, String(value));
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
return [4 /*yield*/, fetch(url.toString(), {
|
|
100
|
-
method: method,
|
|
101
|
-
headers: {
|
|
102
|
-
'Content-Type': 'application/json',
|
|
103
|
-
'x-api-key': this.apiKey,
|
|
104
|
-
},
|
|
105
|
-
body: body ? JSON.stringify(body) : undefined,
|
|
106
|
-
})];
|
|
107
|
-
case 1:
|
|
108
|
-
results = _a.sent();
|
|
109
|
-
if (!!results.ok) return [3 /*break*/, 3];
|
|
110
|
-
return [4 /*yield*/, results.text()];
|
|
111
|
-
case 2:
|
|
112
|
-
errorBody = _a.sent();
|
|
113
|
-
throw new Error("Vortex API request failed: ".concat(results.status, " ").concat(results.statusText, " - ").concat(errorBody));
|
|
114
|
-
case 3: return [2 /*return*/, results.json()];
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
};
|
|
119
|
-
Vortex.prototype.getInvitationsByTarget = function (targetType, targetValue) {
|
|
120
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
121
|
-
var response;
|
|
122
|
-
return __generator(this, function (_a) {
|
|
123
|
-
switch (_a.label) {
|
|
124
|
-
case 0: return [4 /*yield*/, this.vortexApiRequest({
|
|
125
|
-
method: 'GET',
|
|
126
|
-
path: '/api/v1/invitations?targetType',
|
|
127
|
-
queryParams: {
|
|
128
|
-
targetType: targetType,
|
|
129
|
-
targetValue: targetValue,
|
|
130
|
-
}
|
|
131
|
-
})];
|
|
132
|
-
case 1:
|
|
133
|
-
response = _a.sent();
|
|
134
|
-
return [2 /*return*/, response.invitations];
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
};
|
|
139
|
-
Vortex.prototype.getInvitation = function (invitationId) {
|
|
140
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
141
|
-
return __generator(this, function (_a) {
|
|
142
|
-
return [2 /*return*/, this.vortexApiRequest({
|
|
143
|
-
method: 'GET',
|
|
144
|
-
path: "/api/v1/invitations/".concat(invitationId),
|
|
145
|
-
})];
|
|
146
|
-
});
|
|
147
|
-
});
|
|
148
|
-
};
|
|
149
|
-
Vortex.prototype.revokeInvitation = function (invitationId) {
|
|
150
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
151
|
-
return __generator(this, function (_a) {
|
|
152
|
-
return [2 /*return*/, this.vortexApiRequest({
|
|
153
|
-
method: 'DELETE',
|
|
154
|
-
path: "/api/v1/invitations/".concat(invitationId),
|
|
155
|
-
})];
|
|
156
|
-
});
|
|
157
|
-
});
|
|
158
|
-
};
|
|
159
|
-
Vortex.prototype.acceptInvitations = function (invitationIds, target) {
|
|
160
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
161
|
-
var response;
|
|
162
|
-
return __generator(this, function (_a) {
|
|
163
|
-
switch (_a.label) {
|
|
164
|
-
case 0: return [4 /*yield*/, this.vortexApiRequest({
|
|
165
|
-
method: 'POST',
|
|
166
|
-
body: {
|
|
167
|
-
invitationIds: invitationIds,
|
|
168
|
-
target: target,
|
|
169
|
-
},
|
|
170
|
-
path: "/api/v1/invitations/accept",
|
|
171
|
-
})];
|
|
172
|
-
case 1:
|
|
173
|
-
response = _a.sent();
|
|
174
|
-
return [2 /*return*/, response];
|
|
175
|
-
}
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
};
|
|
179
|
-
Vortex.prototype.deleteInvitationsByGroup = function (groupType, groupId) {
|
|
180
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
181
|
-
return __generator(this, function (_a) {
|
|
182
|
-
return [2 /*return*/, this.vortexApiRequest({
|
|
183
|
-
method: 'DELETE',
|
|
184
|
-
path: "/api/v1/invitations/by-group/".concat(groupType, "/").concat(groupId),
|
|
185
|
-
})];
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
};
|
|
189
|
-
Vortex.prototype.getInvitationsByGroup = function (groupType, groupId) {
|
|
190
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
191
|
-
var response;
|
|
192
|
-
return __generator(this, function (_a) {
|
|
193
|
-
switch (_a.label) {
|
|
194
|
-
case 0: return [4 /*yield*/, this.vortexApiRequest({
|
|
195
|
-
method: 'GET',
|
|
196
|
-
path: "/api/v1/invitations/by-group/".concat(groupType, "/").concat(groupId),
|
|
197
|
-
})];
|
|
198
|
-
case 1:
|
|
199
|
-
response = _a.sent();
|
|
200
|
-
return [2 /*return*/, response.invitations];
|
|
201
|
-
}
|
|
202
|
-
});
|
|
203
|
-
});
|
|
204
|
-
};
|
|
205
|
-
Vortex.prototype.reinvite = function (invitationId) {
|
|
206
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
207
|
-
return __generator(this, function (_a) {
|
|
208
|
-
return [2 /*return*/, this.vortexApiRequest({
|
|
209
|
-
method: 'POST',
|
|
210
|
-
path: "/api/v1/invitations/".concat(invitationId, "/reinvite"),
|
|
211
|
-
})];
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
};
|
|
215
|
-
return Vortex;
|
|
216
|
-
}());
|
|
217
|
-
exports.Vortex = Vortex;
|