@scalekit-sdk/node 1.0.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/LICENSE +21 -0
- package/README.md +49 -0
- package/buf.gen.yaml +14 -0
- package/lib/connect.d.ts +9 -0
- package/lib/connect.js +31 -0
- package/lib/connect.js.map +1 -0
- package/lib/connection.d.ts +28 -0
- package/lib/connection.js +68 -0
- package/lib/connection.js.map +1 -0
- package/lib/constants/user.d.ts +4 -0
- package/lib/constants/user.js +24 -0
- package/lib/constants/user.js.map +1 -0
- package/lib/core.d.ts +37 -0
- package/lib/core.js +160 -0
- package/lib/core.js.map +1 -0
- package/lib/domain.d.ts +33 -0
- package/lib/domain.js +74 -0
- package/lib/domain.js.map +1 -0
- package/lib/index.d.ts +5 -0
- package/lib/index.js +26 -0
- package/lib/index.js.map +1 -0
- package/lib/organization.d.ts +64 -0
- package/lib/organization.js +116 -0
- package/lib/organization.js.map +1 -0
- package/lib/pkg/grpc/scalekit/v1/commons/commons_pb.d.ts +20 -0
- package/lib/pkg/grpc/scalekit/v1/commons/commons_pb.js +36 -0
- package/lib/pkg/grpc/scalekit/v1/commons/commons_pb.js.map +1 -0
- package/lib/pkg/grpc/scalekit/v1/connections/connections_connect.d.ts +73 -0
- package/lib/pkg/grpc/scalekit/v1/connections/connections_connect.js +81 -0
- package/lib/pkg/grpc/scalekit/v1/connections/connections_connect.js.map +1 -0
- package/lib/pkg/grpc/scalekit/v1/connections/connections_pb.d.ts +1252 -0
- package/lib/pkg/grpc/scalekit/v1/connections/connections_pb.js +1536 -0
- package/lib/pkg/grpc/scalekit/v1/connections/connections_pb.js.map +1 -0
- package/lib/pkg/grpc/scalekit/v1/domains/domains_connect.d.ts +55 -0
- package/lib/pkg/grpc/scalekit/v1/domains/domains_connect.js +63 -0
- package/lib/pkg/grpc/scalekit/v1/domains/domains_connect.js.map +1 -0
- package/lib/pkg/grpc/scalekit/v1/domains/domains_pb.d.ts +394 -0
- package/lib/pkg/grpc/scalekit/v1/domains/domains_pb.js +469 -0
- package/lib/pkg/grpc/scalekit/v1/domains/domains_pb.js.map +1 -0
- package/lib/pkg/grpc/scalekit/v1/errdetails/errdetails_pb.d.ts +245 -0
- package/lib/pkg/grpc/scalekit/v1/errdetails/errdetails_pb.js +369 -0
- package/lib/pkg/grpc/scalekit/v1/errdetails/errdetails_pb.js.map +1 -0
- package/lib/pkg/grpc/scalekit/v1/options/options_pb.d.ts +98 -0
- package/lib/pkg/grpc/scalekit/v1/options/options_pb.js +135 -0
- package/lib/pkg/grpc/scalekit/v1/options/options_pb.js.map +1 -0
- package/lib/pkg/grpc/scalekit/v1/organizations/organizations_connect.d.ts +92 -0
- package/lib/pkg/grpc/scalekit/v1/organizations/organizations_connect.js +100 -0
- package/lib/pkg/grpc/scalekit/v1/organizations/organizations_connect.js.map +1 -0
- package/lib/pkg/grpc/scalekit/v1/organizations/organizations_pb.d.ts +424 -0
- package/lib/pkg/grpc/scalekit/v1/organizations/organizations_pb.js +559 -0
- package/lib/pkg/grpc/scalekit/v1/organizations/organizations_pb.js.map +1 -0
- package/lib/scalekit.d.ts +60 -0
- package/lib/scalekit.js +140 -0
- package/lib/scalekit.js.map +1 -0
- package/lib/types/scalekit.d.ts +26 -0
- package/lib/types/scalekit.js +10 -0
- package/lib/types/scalekit.js.map +1 -0
- package/lib/types/user.d.ts +56 -0
- package/lib/types/user.js +3 -0
- package/lib/types/user.js.map +1 -0
- package/package.json +45 -0
- package/src/connect.ts +33 -0
- package/src/connection.ts +69 -0
- package/src/constants/user.ts +22 -0
- package/src/core.ts +127 -0
- package/src/domain.ts +75 -0
- package/src/index.ts +7 -0
- package/src/organization.ts +129 -0
- package/src/pkg/grpc/scalekit/v1/commons/commons_pb.ts +36 -0
- package/src/pkg/grpc/scalekit/v1/connections/connections_connect.ts +80 -0
- package/src/pkg/grpc/scalekit/v1/connections/connections_pb.ts +2138 -0
- package/src/pkg/grpc/scalekit/v1/domains/domains_connect.ts +62 -0
- package/src/pkg/grpc/scalekit/v1/domains/domains_pb.ts +687 -0
- package/src/pkg/grpc/scalekit/v1/errdetails/errdetails_pb.ts +461 -0
- package/src/pkg/grpc/scalekit/v1/options/options_pb.ts +156 -0
- package/src/pkg/grpc/scalekit/v1/organizations/organizations_connect.ts +99 -0
- package/src/pkg/grpc/scalekit/v1/organizations/organizations_pb.ts +774 -0
- package/src/scalekit.ts +155 -0
- package/src/types/scalekit.ts +30 -0
- package/src/types/user.ts +59 -0
- package/tsconfig.json +18 -0
package/lib/scalekit.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
const jose = __importStar(require("jose"));
|
|
39
|
+
const qs_1 = __importDefault(require("qs"));
|
|
40
|
+
const connect_1 = __importDefault(require("./connect"));
|
|
41
|
+
const connection_1 = __importDefault(require("./connection"));
|
|
42
|
+
const user_1 = require("./constants/user");
|
|
43
|
+
const core_1 = __importDefault(require("./core"));
|
|
44
|
+
const domain_1 = __importDefault(require("./domain"));
|
|
45
|
+
const organization_1 = __importDefault(require("./organization"));
|
|
46
|
+
const scalekit_1 = require("./types/scalekit");
|
|
47
|
+
const authorizeEndpoint = "oauth/authorize";
|
|
48
|
+
/**
|
|
49
|
+
* To initiate scalekit
|
|
50
|
+
* @param {string} envUrl The environment url
|
|
51
|
+
* @param {string} clientId The client id
|
|
52
|
+
* @param {string} clientSecret The client secret
|
|
53
|
+
* @returns {Scalekit} Returns the scalekit instance
|
|
54
|
+
* @example
|
|
55
|
+
* const scalekit = new Scalekit(envUrl, clientId, clientSecret);
|
|
56
|
+
*/
|
|
57
|
+
class Scalekit {
|
|
58
|
+
constructor(envUrl, clientId, clientSecret) {
|
|
59
|
+
this.coreClient = new core_1.default(envUrl, clientId, clientSecret);
|
|
60
|
+
this.grpcConnect = new connect_1.default(this.coreClient);
|
|
61
|
+
this.organization = new organization_1.default(this.grpcConnect, this.coreClient);
|
|
62
|
+
this.connection = new connection_1.default(this.grpcConnect, this.coreClient);
|
|
63
|
+
this.domain = new domain_1.default(this.grpcConnect, this.coreClient);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns the authorization url to initiate the authentication request.
|
|
67
|
+
* @param {string} redirectUri Redirect uri
|
|
68
|
+
* @param {AuthorizationUrlOptions} options Authorization url options
|
|
69
|
+
* @param {string[]} options.scopes Scopes to request from the user
|
|
70
|
+
* @param {string} options.state State parameter
|
|
71
|
+
* @param {string} options.nonce Nonce parameter
|
|
72
|
+
* @param {string} options.loginHint Login hint parameter
|
|
73
|
+
* @param {string} options.domainHint Domain hint parameter
|
|
74
|
+
* @param {string} options.connectionId Connection id parameter
|
|
75
|
+
* @param {string} options.organizationId Organization id parameter
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* const scalekit = new Scalekit(envUrl, clientId, clientSecret);
|
|
79
|
+
* const authorizationUrl = scalekit.getAuthorizationUrl(redirectUri, { scopes: ['openid', 'profile'] });
|
|
80
|
+
* @returns {string} authorization url
|
|
81
|
+
*/
|
|
82
|
+
getAuthorizationUrl(redirectUri, options) {
|
|
83
|
+
var _a;
|
|
84
|
+
const defaultOptions = {
|
|
85
|
+
scopes: ['openid', 'profile']
|
|
86
|
+
};
|
|
87
|
+
options = Object.assign(Object.assign({}, defaultOptions), options);
|
|
88
|
+
const qs = qs_1.default.stringify(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ response_type: 'code', client_id: this.coreClient.clientId, redirect_uri: redirectUri, scope: (_a = options.scopes) === null || _a === void 0 ? void 0 : _a.join(" ") }, (options.state && { state: options.state })), (options.nonce && { nonce: options.nonce })), (options.loginHint && { login_hint: options.loginHint })), (options.domainHint && { domain_hint: options.domainHint })), (options.domainHint && { domain: options.domainHint })), (options.connectionId && { connection_id: options.connectionId })), (options.organizationId && { organization_id: options.organizationId })));
|
|
89
|
+
return `${this.coreClient.envUrl}/${authorizeEndpoint}?${qs}`;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Authenticate with the code
|
|
93
|
+
* @param {CodeAuthenticationOptions} options Code authentication options
|
|
94
|
+
* @param {string} options.code Code
|
|
95
|
+
* @param {string} options.redirectUri Redirect uri
|
|
96
|
+
* @param {string} options.codeVerifier Code verifier
|
|
97
|
+
* @returns {Promise<{ user: Partial<User>, idToken: string, accessToken: string }>} Returns user, id token and access token
|
|
98
|
+
*/
|
|
99
|
+
authenticateWithCode(options) {
|
|
100
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
101
|
+
const res = yield this.coreClient.authenticate(qs_1.default.stringify(Object.assign({ code: options.code, redirect_uri: options.redirectUri, grant_type: scalekit_1.GrantType.AuthorizationCode, client_id: this.coreClient.clientId, client_secret: this.coreClient.clientSecret }, (options.codeVerifier && { code_verifier: options.codeVerifier }))));
|
|
102
|
+
const { id_token, access_token } = res.data;
|
|
103
|
+
const claims = jose.decodeJwt(id_token);
|
|
104
|
+
const user = {};
|
|
105
|
+
for (const [k, v] of Object.entries(claims)) {
|
|
106
|
+
if (user_1.IdTokenClaimToUserMap[k]) {
|
|
107
|
+
user[user_1.IdTokenClaimToUserMap[k]] = v;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return {
|
|
111
|
+
user,
|
|
112
|
+
idToken: id_token,
|
|
113
|
+
accessToken: access_token
|
|
114
|
+
};
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Validates the access token.
|
|
119
|
+
*
|
|
120
|
+
* @param {string} token The token to be validated.
|
|
121
|
+
* @return {Promise<boolean>} Returns true if the token is valid, false otherwise.
|
|
122
|
+
*/
|
|
123
|
+
validateAccessToken(token) {
|
|
124
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
125
|
+
yield this.coreClient.getJwks();
|
|
126
|
+
const JWKS = jose.createLocalJWKSet({
|
|
127
|
+
keys: this.coreClient.keys
|
|
128
|
+
});
|
|
129
|
+
try {
|
|
130
|
+
yield jose.jwtVerify(token, JWKS);
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
catch (error) {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.default = Scalekit;
|
|
140
|
+
//# sourceMappingURL=scalekit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scalekit.js","sourceRoot":"","sources":["../src/scalekit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export declare enum GrantType {
|
|
2
|
+
AuthorizationCode = "authorization_code",
|
|
3
|
+
RefreshToken = "refresh_token",
|
|
4
|
+
ClientCredentials = "client_credentials"
|
|
5
|
+
}
|
|
6
|
+
export type AuthorizationUrlOptions = {
|
|
7
|
+
connectionId?: string;
|
|
8
|
+
organizationId?: string;
|
|
9
|
+
scopes?: string[];
|
|
10
|
+
state?: string;
|
|
11
|
+
nonce?: string;
|
|
12
|
+
domainHint?: string;
|
|
13
|
+
loginHint?: string;
|
|
14
|
+
};
|
|
15
|
+
export type CodeAuthenticationOptions = {
|
|
16
|
+
code: string;
|
|
17
|
+
redirectUri: string;
|
|
18
|
+
codeVerifier?: string;
|
|
19
|
+
};
|
|
20
|
+
export type RefreshTokenAuthenticationOptions = {
|
|
21
|
+
code: string;
|
|
22
|
+
redirectUri: string;
|
|
23
|
+
};
|
|
24
|
+
export type AuthenticationOptions = {
|
|
25
|
+
refreshToken: string;
|
|
26
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.GrantType = void 0;
|
|
4
|
+
var GrantType;
|
|
5
|
+
(function (GrantType) {
|
|
6
|
+
GrantType["AuthorizationCode"] = "authorization_code";
|
|
7
|
+
GrantType["RefreshToken"] = "refresh_token";
|
|
8
|
+
GrantType["ClientCredentials"] = "client_credentials";
|
|
9
|
+
})(GrantType || (exports.GrantType = GrantType = {}));
|
|
10
|
+
//# sourceMappingURL=scalekit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scalekit.js","sourceRoot":"","sources":["../../src/types/scalekit.ts"],"names":[],"mappings":";;;AAAA,IAAY,SAIX;AAJD,WAAY,SAAS;IACnB,qDAAwC,CAAA;IACxC,2CAA8B,CAAA;IAC9B,qDAAwC,CAAA;AAC1C,CAAC,EAJW,SAAS,yBAAT,SAAS,QAIpB"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export type User = {
|
|
2
|
+
id: string;
|
|
3
|
+
username: string | undefined;
|
|
4
|
+
name: string;
|
|
5
|
+
givenName: string;
|
|
6
|
+
familyName: string | undefined;
|
|
7
|
+
email: string;
|
|
8
|
+
emailVerified: boolean;
|
|
9
|
+
phoneNumber: string | undefined;
|
|
10
|
+
phoneNumberVerified: boolean | undefined;
|
|
11
|
+
profile: string | undefined;
|
|
12
|
+
picture: string | undefined;
|
|
13
|
+
gender: string | undefined;
|
|
14
|
+
birthDate: string | undefined;
|
|
15
|
+
zoneInfo: string | undefined;
|
|
16
|
+
locale: string | undefined;
|
|
17
|
+
updatedAt: string | undefined;
|
|
18
|
+
identities: Identity[];
|
|
19
|
+
metadata: string | undefined;
|
|
20
|
+
};
|
|
21
|
+
export type Identity = {
|
|
22
|
+
connectionId: string;
|
|
23
|
+
organizationId: string;
|
|
24
|
+
connectionType: string;
|
|
25
|
+
providerName: string;
|
|
26
|
+
social: boolean;
|
|
27
|
+
providerRawAttributes: string;
|
|
28
|
+
};
|
|
29
|
+
export type IdTokenClaimIdentity = {
|
|
30
|
+
connection_id: string;
|
|
31
|
+
organization_id: string;
|
|
32
|
+
connection_type: string;
|
|
33
|
+
provider_name: string;
|
|
34
|
+
social: boolean;
|
|
35
|
+
provider_raw_attributes: string;
|
|
36
|
+
};
|
|
37
|
+
export type IdTokenClaim = {
|
|
38
|
+
sub: string;
|
|
39
|
+
name: string;
|
|
40
|
+
preferred_username: string | undefined;
|
|
41
|
+
given_name: string;
|
|
42
|
+
family_name: string | undefined;
|
|
43
|
+
email: string;
|
|
44
|
+
email_verified: boolean;
|
|
45
|
+
phone_number: string | undefined;
|
|
46
|
+
phone_number_verified: boolean | undefined;
|
|
47
|
+
profile: string | undefined;
|
|
48
|
+
picture: string | undefined;
|
|
49
|
+
gender: string | undefined;
|
|
50
|
+
birthdate: string | undefined;
|
|
51
|
+
zoneinfo: string | undefined;
|
|
52
|
+
locale: string | undefined;
|
|
53
|
+
updated_at: string | undefined;
|
|
54
|
+
identities: IdTokenClaimIdentity[];
|
|
55
|
+
metadata: string | undefined;
|
|
56
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user.js","sourceRoot":"","sources":["../../src/types/user.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1.0.0",
|
|
3
|
+
"name": "@scalekit-sdk/node",
|
|
4
|
+
"description": "Scalekit Node SDK",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"typings": "lib/index.d.ts",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/scalekit-inc/scalekit-sdk-node.git"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"generate": "npx buf generate $npm_config_src",
|
|
13
|
+
"build": "rm -rf lib && tsc",
|
|
14
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"scalekit"
|
|
18
|
+
],
|
|
19
|
+
"author": "Scalekit Team",
|
|
20
|
+
"license": "ISC",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@connectrpc/connect": "^1.4.0",
|
|
23
|
+
"@connectrpc/connect-node": "^1.4.0",
|
|
24
|
+
"axios": "^1.6.8",
|
|
25
|
+
"jose": "^5.2.4",
|
|
26
|
+
"qs": "^6.12.1"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@bufbuild/buf": "^1.30.1",
|
|
30
|
+
"@bufbuild/protobuf": "^1.8.0",
|
|
31
|
+
"@bufbuild/protoc-gen-es": "^1.8.0",
|
|
32
|
+
"@connectrpc/protoc-gen-connect-es": "^1.4.0",
|
|
33
|
+
"@types/node": "^20.12.7",
|
|
34
|
+
"@types/qs": "^6.9.15",
|
|
35
|
+
"typescript": "^5.4.5"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/scalekit-inc/scalekit-sdk-node/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/scalekit-inc/scalekit-sdk-node#readme",
|
|
41
|
+
"directories": {
|
|
42
|
+
"example": "examples",
|
|
43
|
+
"lib": "lib"
|
|
44
|
+
}
|
|
45
|
+
}
|
package/src/connect.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { ServiceType } from '@bufbuild/protobuf';
|
|
2
|
+
import { PromiseClient, Transport, createPromiseClient } from '@connectrpc/connect';
|
|
3
|
+
import { createGrpcTransport } from '@connectrpc/connect-node';
|
|
4
|
+
import CoreClient from './core';
|
|
5
|
+
|
|
6
|
+
export default class GrpcConnect {
|
|
7
|
+
private transport: Transport;
|
|
8
|
+
constructor(
|
|
9
|
+
private readonly coreClient: CoreClient
|
|
10
|
+
) {
|
|
11
|
+
this.transport = createGrpcTransport({
|
|
12
|
+
baseUrl: this.coreClient.envUrl,
|
|
13
|
+
httpVersion: "2",
|
|
14
|
+
interceptors: [
|
|
15
|
+
(next) => {
|
|
16
|
+
return (req) => {
|
|
17
|
+
req.header.set("User-Agent", this.coreClient.userAgent)
|
|
18
|
+
req.header.set("x-sdk-version", this.coreClient.sdkVersion)
|
|
19
|
+
req.header.set("x-api-version", this.coreClient.apiVersion)
|
|
20
|
+
if (this.coreClient.accessToken) {
|
|
21
|
+
req.header.set("Authorization", `Bearer ${this.coreClient.accessToken}`)
|
|
22
|
+
}
|
|
23
|
+
return next(req)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
createClient<T extends ServiceType>(service: T): PromiseClient<T> {
|
|
31
|
+
return createPromiseClient(service, this.transport);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { PromiseClient } from '@connectrpc/connect';
|
|
2
|
+
import GrpcConnect from './connect';
|
|
3
|
+
import CoreClient from './core';
|
|
4
|
+
import { ConnectionService } from './pkg/grpc/scalekit/v1/connections/connections_connect';
|
|
5
|
+
import { GetConnectionResponse, ListConnectionsResponse } from './pkg/grpc/scalekit/v1/connections/connections_pb';
|
|
6
|
+
|
|
7
|
+
export default class ConnectionClient {
|
|
8
|
+
private client: PromiseClient<typeof ConnectionService>;
|
|
9
|
+
constructor(
|
|
10
|
+
private readonly grpcConncet: GrpcConnect,
|
|
11
|
+
private readonly coreClient: CoreClient
|
|
12
|
+
) {
|
|
13
|
+
this.client = this.grpcConncet.createClient(ConnectionService);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Get a connection by id and organization id
|
|
18
|
+
* @param id The connection id
|
|
19
|
+
* @param organizationId The organization id
|
|
20
|
+
* @returns {Promise<GetConnectionResponse>} The connection
|
|
21
|
+
*/
|
|
22
|
+
async getConnection(id: string, organizationId: string): Promise<GetConnectionResponse> {
|
|
23
|
+
return this.coreClient.connectExec(
|
|
24
|
+
this.client.getConnection,
|
|
25
|
+
{
|
|
26
|
+
id,
|
|
27
|
+
identities: {
|
|
28
|
+
case: 'organizationId',
|
|
29
|
+
value: organizationId
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* List connections by domain
|
|
37
|
+
* @param domain The domain
|
|
38
|
+
* @returns {Promise<ListConnectionsResponse>} The connection
|
|
39
|
+
*/
|
|
40
|
+
async listConnectionsByDomain(domain: string): Promise<ListConnectionsResponse> {
|
|
41
|
+
return this.coreClient.connectExec(
|
|
42
|
+
this.client.listConnections,
|
|
43
|
+
{
|
|
44
|
+
identities: {
|
|
45
|
+
case: 'domain',
|
|
46
|
+
value: domain
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* List connections by organization id
|
|
54
|
+
* @param organizationId The organization id
|
|
55
|
+
* @returns {Promise<ListConnectionsResponse>} The list of connections
|
|
56
|
+
*/
|
|
57
|
+
async listConnections(organizationId: string): Promise<ListConnectionsResponse> {
|
|
58
|
+
return this.coreClient.connectExec(
|
|
59
|
+
this.client.listConnections,
|
|
60
|
+
{
|
|
61
|
+
identities: {
|
|
62
|
+
case: 'organizationId',
|
|
63
|
+
value: organizationId
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { IdTokenClaim, User } from '../types/user';
|
|
2
|
+
|
|
3
|
+
export const IdTokenClaimToUserMap: { [k in keyof IdTokenClaim]: keyof User } = {
|
|
4
|
+
"sub": "id",
|
|
5
|
+
"name": "name",
|
|
6
|
+
"preferred_username": "username",
|
|
7
|
+
"given_name": "givenName",
|
|
8
|
+
"family_name": "familyName",
|
|
9
|
+
"email": "email",
|
|
10
|
+
"email_verified": "emailVerified",
|
|
11
|
+
"phone_number": "phoneNumber",
|
|
12
|
+
"phone_number_verified": "phoneNumberVerified",
|
|
13
|
+
"profile": 'profile',
|
|
14
|
+
"picture": "picture",
|
|
15
|
+
"gender": "gender",
|
|
16
|
+
"birthdate": "birthDate",
|
|
17
|
+
"zoneinfo": "zoneInfo",
|
|
18
|
+
"locale": "locale",
|
|
19
|
+
"updated_at": "updatedAt",
|
|
20
|
+
"identities": "identities",
|
|
21
|
+
"metadata": "metadata"
|
|
22
|
+
}
|
package/src/core.ts
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Code, ConnectError } from '@connectrpc/connect';
|
|
2
|
+
import axios, { Axios, AxiosError, AxiosResponse, HttpStatusCode } from "axios";
|
|
3
|
+
import { JWK } from 'jose';
|
|
4
|
+
import os from "os";
|
|
5
|
+
import QueryString from "qs";
|
|
6
|
+
import { GrantType } from './types/scalekit';
|
|
7
|
+
import { ErrorInfo } from './pkg/grpc/scalekit/v1/errdetails/errdetails_pb';
|
|
8
|
+
|
|
9
|
+
const tokenEndpoint = "oauth/token";
|
|
10
|
+
const jwksEndpoint = "keys";
|
|
11
|
+
export default class CoreClient {
|
|
12
|
+
public keys: JWK[] = [];
|
|
13
|
+
public accessToken: string | null = null;
|
|
14
|
+
public axios: Axios;
|
|
15
|
+
public sdkVersion = `Scalekit-Node/1.0.0`;
|
|
16
|
+
public apiVersion = "20240430";
|
|
17
|
+
public userAgent = `${this.sdkVersion} Node/${process.version} (${process.platform}; ${os.arch()})`;
|
|
18
|
+
constructor(
|
|
19
|
+
readonly envUrl: string,
|
|
20
|
+
readonly clientId: string,
|
|
21
|
+
readonly clientSecret: string
|
|
22
|
+
) {
|
|
23
|
+
this.axios = axios.create({ baseURL: envUrl });
|
|
24
|
+
this.axios.interceptors.request.use((config) => {
|
|
25
|
+
config.headers["User-Agent"] = this.userAgent;
|
|
26
|
+
config.headers["x-sdk-version"] = this.sdkVersion;
|
|
27
|
+
config.headers["x-api-version"] = this.apiVersion;
|
|
28
|
+
if (this.accessToken) {
|
|
29
|
+
config.headers["Authorization"] = `Bearer ${this.accessToken}`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return config;
|
|
33
|
+
});
|
|
34
|
+
this.authenticateClient();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private async authenticateClient() {
|
|
38
|
+
const res = await this.authenticate(QueryString.stringify({
|
|
39
|
+
grant_type: GrantType.ClientCredentials,
|
|
40
|
+
client_id: this.clientId,
|
|
41
|
+
client_secret: this.clientSecret
|
|
42
|
+
}))
|
|
43
|
+
|
|
44
|
+
this.accessToken = res.data.access_token;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Authenticate with the code
|
|
48
|
+
* @param {string} data Data to authenticate
|
|
49
|
+
* @returns {Promise<AxiosResponse<{ access_token: string, id_token: string }>>} Returns access token and id token
|
|
50
|
+
*/
|
|
51
|
+
async authenticate(data: string): Promise<AxiosResponse<{ access_token: string; id_token: string; }, any>> {
|
|
52
|
+
return this.axios.post<{ access_token: string, id_token: string }>(
|
|
53
|
+
tokenEndpoint,
|
|
54
|
+
data,
|
|
55
|
+
{
|
|
56
|
+
headers: {
|
|
57
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get the JWKS from the server and store it in the client instance
|
|
65
|
+
* @returns {Promise<void>} Returns nothing
|
|
66
|
+
*/
|
|
67
|
+
async getJwks(): Promise<void> {
|
|
68
|
+
if (this.keys.length) {
|
|
69
|
+
return Promise.resolve();
|
|
70
|
+
}
|
|
71
|
+
const { data: { keys } } = await this.axios.get<{ keys: JWK[] }>(jwksEndpoint);
|
|
72
|
+
this.keys = keys;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
*
|
|
77
|
+
* @param fn Function to execute
|
|
78
|
+
* @param data Data to pass to the function
|
|
79
|
+
* @param retryLeft Number of retries left
|
|
80
|
+
* @returns {Promise<TResponse>} Returns the response
|
|
81
|
+
*/
|
|
82
|
+
async connectExec<TRequest, TResponse>(
|
|
83
|
+
fn: (request: TRequest) => Promise<TResponse>,
|
|
84
|
+
data: TRequest,
|
|
85
|
+
retryLeft: number = 1,
|
|
86
|
+
): Promise<TResponse> {
|
|
87
|
+
try {
|
|
88
|
+
const res = await fn(data);
|
|
89
|
+
return res;
|
|
90
|
+
} catch (error) {
|
|
91
|
+
if (retryLeft > 0) {
|
|
92
|
+
let isUnauthenticatedError = false;
|
|
93
|
+
if (error instanceof AxiosError) {
|
|
94
|
+
if (error.status == HttpStatusCode.Unauthorized) {
|
|
95
|
+
isUnauthenticatedError = true;
|
|
96
|
+
} else {
|
|
97
|
+
throw new Error(error.message);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// ConnectError is a custom error class that extends Error class and has a code property
|
|
101
|
+
if (error instanceof ConnectError) {
|
|
102
|
+
if (error.code == Code.Unauthenticated) {
|
|
103
|
+
isUnauthenticatedError = true;
|
|
104
|
+
} else {
|
|
105
|
+
if (error.code == Code.InvalidArgument) {
|
|
106
|
+
const message = error.findDetails(ErrorInfo).map((detail) => {
|
|
107
|
+
if (detail.validationErrorInfo) {
|
|
108
|
+
return detail.validationErrorInfo.fieldViolations.map((fv) => {
|
|
109
|
+
return `${fv.field}: ${fv.description}`
|
|
110
|
+
}).join("\n")
|
|
111
|
+
}
|
|
112
|
+
return error.message;
|
|
113
|
+
}).join("\n")
|
|
114
|
+
throw new Error(message);
|
|
115
|
+
}
|
|
116
|
+
throw new Error(error.message);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (isUnauthenticatedError) {
|
|
120
|
+
await this.authenticateClient();
|
|
121
|
+
return this.connectExec(fn, data, retryLeft - 1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
package/src/domain.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { PromiseClient } from '@connectrpc/connect';
|
|
2
|
+
import GrpcConnect from './connect';
|
|
3
|
+
import CoreClient from './core';
|
|
4
|
+
import { DomainService } from './pkg/grpc/scalekit/v1/domains/domains_connect';
|
|
5
|
+
import { CreateDomainResponse, GetDomainResponse, ListDomainResponse } from './pkg/grpc/scalekit/v1/domains/domains_pb';
|
|
6
|
+
|
|
7
|
+
export default class DomainClient {
|
|
8
|
+
private client: PromiseClient<typeof DomainService>;
|
|
9
|
+
constructor(
|
|
10
|
+
private readonly grpcConncet: GrpcConnect,
|
|
11
|
+
private readonly coreClient: CoreClient
|
|
12
|
+
) {
|
|
13
|
+
this.client = this.grpcConncet.createClient(DomainService);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Create a domain for an organization with the given name. Optionally, you can provide an external id.
|
|
18
|
+
* @param {string} organizationId The organization id
|
|
19
|
+
* @param {string} name The domain name
|
|
20
|
+
* @returns {Promise<CreateDomainResponse>} The created domain
|
|
21
|
+
*/
|
|
22
|
+
async createDomain(organizationId: string, name: string): Promise<CreateDomainResponse> {
|
|
23
|
+
return this.coreClient.connectExec(
|
|
24
|
+
this.client.createDomain,
|
|
25
|
+
{
|
|
26
|
+
identities: {
|
|
27
|
+
case: 'organizationId',
|
|
28
|
+
value: organizationId
|
|
29
|
+
},
|
|
30
|
+
domain: {
|
|
31
|
+
domain: name
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get a domain by id
|
|
39
|
+
* @param {object} options The options to get a domain
|
|
40
|
+
* @param {string} options.id The domain id
|
|
41
|
+
* @param {string} options.organizationId The organization id
|
|
42
|
+
* @returns {Promise<GetDomainResponse>} The domain
|
|
43
|
+
*/
|
|
44
|
+
async getDomain(options: { id: string, organizationId: string }): Promise<GetDomainResponse> {
|
|
45
|
+
const { id, organizationId } = options;
|
|
46
|
+
return this.coreClient.connectExec(
|
|
47
|
+
this.client.getDomain,
|
|
48
|
+
{
|
|
49
|
+
id,
|
|
50
|
+
identities: {
|
|
51
|
+
case: 'organizationId',
|
|
52
|
+
value: organizationId
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* List domains for an organization
|
|
60
|
+
* @param organizationId The organization id
|
|
61
|
+
* @returns {Promise<ListDomainResponse>} The list of domains for the organization
|
|
62
|
+
*/
|
|
63
|
+
async listDomains(organizationId: string): Promise<ListDomainResponse> {
|
|
64
|
+
return this.coreClient.connectExec(
|
|
65
|
+
this.client.listDomains,
|
|
66
|
+
{
|
|
67
|
+
identities: {
|
|
68
|
+
case: 'organizationId',
|
|
69
|
+
value: organizationId
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|