@vybit/oauth2-sdk 1.0.4 → 1.2.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 +61 -30
- package/dist/oauth2-client.d.ts +50 -24
- package/dist/oauth2-client.d.ts.map +1 -1
- package/dist/oauth2-client.js +59 -96
- package/dist/oauth2-client.js.map +1 -1
- package/dist/types.d.ts +3 -55
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +19 -0
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -4,7 +4,9 @@ OAuth 2.0 authentication SDK for Vybit.
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The OAuth2 SDK handles the authorization flow for user-facing applications. It provides authorization URL generation, token exchange, and token verification.
|
|
8
|
+
|
|
9
|
+
Once you have an access token, use `VybitAPIClient` from `@vybit/api-sdk` with `{ accessToken }` to make API calls on behalf of the user.
|
|
8
10
|
|
|
9
11
|
## Setup
|
|
10
12
|
|
|
@@ -15,23 +17,24 @@ Complete OAuth2 implementation for Vybit authentication, including authorization
|
|
|
15
17
|
## Installation
|
|
16
18
|
|
|
17
19
|
```bash
|
|
18
|
-
npm install @vybit/oauth2-sdk
|
|
20
|
+
npm install @vybit/oauth2-sdk @vybit/api-sdk
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
## Quick Start
|
|
22
24
|
|
|
23
25
|
```typescript
|
|
24
26
|
import { VybitOAuth2Client } from '@vybit/oauth2-sdk';
|
|
27
|
+
import { VybitAPIClient } from '@vybit/api-sdk';
|
|
25
28
|
|
|
26
29
|
// Create client with your OAuth2 credentials
|
|
27
|
-
const
|
|
30
|
+
const oauthClient = new VybitOAuth2Client({
|
|
28
31
|
clientId: 'your-client-id',
|
|
29
32
|
clientSecret: 'your-client-secret',
|
|
30
33
|
redirectUri: 'https://yourapp.com/oauth/callback'
|
|
31
34
|
});
|
|
32
35
|
|
|
33
36
|
// Step 1: Generate authorization URL
|
|
34
|
-
const authUrl =
|
|
37
|
+
const authUrl = oauthClient.getAuthorizationUrl({
|
|
35
38
|
state: 'unique-state-value',
|
|
36
39
|
scope: 'read write'
|
|
37
40
|
});
|
|
@@ -39,20 +42,62 @@ const authUrl = client.getAuthorizationUrl({
|
|
|
39
42
|
// Redirect user to authUrl...
|
|
40
43
|
|
|
41
44
|
// Step 2: Exchange authorization code for token
|
|
42
|
-
const token = await
|
|
45
|
+
const token = await oauthClient.exchangeCodeForToken('auth-code-from-callback');
|
|
46
|
+
|
|
47
|
+
// Step 3: Use the token with the API SDK
|
|
48
|
+
const apiClient = new VybitAPIClient({
|
|
49
|
+
accessToken: token.access_token
|
|
50
|
+
});
|
|
43
51
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
await client.sendVybitNotification('trigger-key', {
|
|
52
|
+
const vybits = await apiClient.listVybits();
|
|
53
|
+
await apiClient.triggerVybit('vybit-key', {
|
|
47
54
|
message: 'Hello from your app!'
|
|
48
55
|
});
|
|
49
56
|
```
|
|
50
57
|
|
|
58
|
+
## PKCE Flow (Public Clients)
|
|
59
|
+
|
|
60
|
+
For native apps, SPAs, MCP clients, and other public clients that cannot store a client secret:
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { VybitOAuth2Client } from '@vybit/oauth2-sdk';
|
|
64
|
+
import { generateCodeVerifier, generateCodeChallenge } from '@vybit/core';
|
|
65
|
+
|
|
66
|
+
// No clientSecret needed
|
|
67
|
+
const oauthClient = new VybitOAuth2Client({
|
|
68
|
+
clientId: 'your-client-id',
|
|
69
|
+
redirectUri: 'https://yourapp.com/oauth/callback'
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
// Step 1: Generate PKCE verifier and challenge
|
|
73
|
+
const codeVerifier = generateCodeVerifier();
|
|
74
|
+
const codeChallenge = await generateCodeChallenge(codeVerifier);
|
|
75
|
+
|
|
76
|
+
// Step 2: Generate authorization URL with code_challenge
|
|
77
|
+
const authUrl = oauthClient.getAuthorizationUrl({
|
|
78
|
+
state: 'unique-state-value',
|
|
79
|
+
codeChallenge
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Redirect user to authUrl, store codeVerifier in session...
|
|
83
|
+
|
|
84
|
+
// Step 3: Exchange code with code_verifier (no client_secret needed)
|
|
85
|
+
const token = await oauthClient.exchangeCodeForToken(
|
|
86
|
+
'auth-code-from-callback',
|
|
87
|
+
codeVerifier
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
// Step 4: Use the token with the API SDK
|
|
91
|
+
const apiClient = new VybitAPIClient({
|
|
92
|
+
accessToken: token.access_token
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
51
96
|
## Environment Management
|
|
52
97
|
|
|
53
|
-
The SDK
|
|
98
|
+
The SDK uses production Vybit endpoints:
|
|
54
99
|
- **Authentication**: `https://app.vybit.net`
|
|
55
|
-
- **API
|
|
100
|
+
- **API** (via `@vybit/api-sdk`): `https://api.vybit.net/v1`
|
|
56
101
|
|
|
57
102
|
For different environments (dev/staging/prod), create separate Vybit accounts with their own OAuth credentials.
|
|
58
103
|
|
|
@@ -71,22 +116,15 @@ new VybitOAuth2Client(config: OAuth2Config)
|
|
|
71
116
|
- Generates OAuth2 authorization URL for user redirection
|
|
72
117
|
- Returns complete URL including all required parameters
|
|
73
118
|
|
|
74
|
-
**`exchangeCodeForToken(code: string): Promise<TokenResponse>`**
|
|
119
|
+
**`exchangeCodeForToken(code: string, codeVerifier?: string): Promise<TokenResponse>`**
|
|
75
120
|
- Exchanges authorization code for access token
|
|
76
|
-
-
|
|
121
|
+
- Pass `codeVerifier` for PKCE flow (omits `client_secret` if not configured)
|
|
122
|
+
- Automatically stores token for subsequent `verifyToken()` calls
|
|
77
123
|
|
|
78
124
|
**`verifyToken(accessToken?: string): Promise<boolean>`**
|
|
79
125
|
- Verifies if an access token is valid
|
|
80
126
|
- Uses stored token if none provided
|
|
81
127
|
|
|
82
|
-
**`getVybitList(accessToken?: string): Promise<Vybit[]>`**
|
|
83
|
-
- Fetches user's vybit notifications
|
|
84
|
-
- Requires valid access token
|
|
85
|
-
|
|
86
|
-
**`sendVybitNotification(triggerKey: string, options?: TriggerOptions, accessToken?: string): Promise<TriggerResponse>`**
|
|
87
|
-
- Triggers a vybit notification
|
|
88
|
-
- Supports custom message, images, and links
|
|
89
|
-
|
|
90
128
|
**`setAccessToken(token: string): void`**
|
|
91
129
|
- Manually set access token
|
|
92
130
|
|
|
@@ -99,7 +137,7 @@ new VybitOAuth2Client(config: OAuth2Config)
|
|
|
99
137
|
import { VybitAuthError, VybitAPIError, VybitValidationError } from '@vybit/oauth2-sdk';
|
|
100
138
|
|
|
101
139
|
try {
|
|
102
|
-
const token = await
|
|
140
|
+
const token = await oauthClient.exchangeCodeForToken(code);
|
|
103
141
|
} catch (error) {
|
|
104
142
|
if (error instanceof VybitAuthError) {
|
|
105
143
|
// Handle authentication errors
|
|
@@ -118,7 +156,7 @@ Full TypeScript support with comprehensive type definitions:
|
|
|
118
156
|
```typescript
|
|
119
157
|
interface OAuth2Config {
|
|
120
158
|
clientId: string;
|
|
121
|
-
clientSecret
|
|
159
|
+
clientSecret?: string; // Optional for PKCE-only public clients
|
|
122
160
|
redirectUri: string;
|
|
123
161
|
}
|
|
124
162
|
|
|
@@ -129,15 +167,8 @@ interface TokenResponse {
|
|
|
129
167
|
refresh_token?: string;
|
|
130
168
|
scope?: string;
|
|
131
169
|
}
|
|
132
|
-
|
|
133
|
-
interface TriggerOptions {
|
|
134
|
-
message?: string;
|
|
135
|
-
imageUrl?: string; // Must be a direct link to a JPG, PNG, or GIF image
|
|
136
|
-
linkUrl?: string;
|
|
137
|
-
log?: string;
|
|
138
|
-
}
|
|
139
170
|
```
|
|
140
171
|
|
|
141
172
|
## License
|
|
142
173
|
|
|
143
|
-
MIT
|
|
174
|
+
MIT
|
package/dist/oauth2-client.d.ts
CHANGED
|
@@ -1,27 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { OAuth2Config, TokenResponse, AuthorizationUrlOptions, TriggerOptions, TriggerResponse } from './types';
|
|
1
|
+
import { OAuth2Config, TokenResponse, AuthorizationUrlOptions } from '@vybit/core';
|
|
3
2
|
/**
|
|
4
|
-
* OAuth2 client for Vybit authentication
|
|
3
|
+
* OAuth2 client for Vybit authentication
|
|
5
4
|
*
|
|
6
|
-
* This client handles the
|
|
7
|
-
*
|
|
5
|
+
* This client handles the OAuth2 authorization flow for Vybit, including
|
|
6
|
+
* authorization URL generation, token exchange, and token verification.
|
|
7
|
+
*
|
|
8
|
+
* Once you have obtained an access token, use {@link VybitAPIClient} from
|
|
9
|
+
* `@vybit/api-sdk` with the `accessToken` option for full Developer API access.
|
|
8
10
|
*
|
|
9
11
|
* @example
|
|
10
12
|
* ```typescript
|
|
11
|
-
*
|
|
13
|
+
* import { VybitOAuth2Client } from '@vybit/oauth2-sdk';
|
|
14
|
+
* import { VybitAPIClient } from '@vybit/api-sdk';
|
|
15
|
+
*
|
|
16
|
+
* // 1. Set up OAuth2 client
|
|
17
|
+
* const oauth = new VybitOAuth2Client({
|
|
12
18
|
* clientId: 'your-client-id',
|
|
13
19
|
* clientSecret: 'your-client-secret',
|
|
14
20
|
* redirectUri: 'https://yourapp.com/oauth/callback'
|
|
15
21
|
* });
|
|
16
22
|
*
|
|
17
|
-
* // Generate authorization URL
|
|
18
|
-
* const authUrl =
|
|
23
|
+
* // 2. Generate authorization URL and redirect user
|
|
24
|
+
* const authUrl = oauth.getAuthorizationUrl();
|
|
25
|
+
*
|
|
26
|
+
* // 3. Exchange authorization code for token (in callback handler)
|
|
27
|
+
* const token = await oauth.exchangeCodeForToken(authCode);
|
|
28
|
+
*
|
|
29
|
+
* // --- PKCE flow (public clients, no client_secret needed) ---
|
|
30
|
+
* import { generateCodeVerifier, generateCodeChallenge } from '@vybit/core';
|
|
19
31
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
32
|
+
* const pkceClient = new VybitOAuth2Client({
|
|
33
|
+
* clientId: 'your-client-id',
|
|
34
|
+
* redirectUri: 'https://yourapp.com/oauth/callback'
|
|
35
|
+
* });
|
|
36
|
+
* const verifier = generateCodeVerifier();
|
|
37
|
+
* const challenge = await generateCodeChallenge(verifier);
|
|
38
|
+
* const pkceAuthUrl = pkceClient.getAuthorizationUrl({ codeChallenge: challenge });
|
|
39
|
+
* const pkceToken = await pkceClient.exchangeCodeForToken(authCode, verifier);
|
|
22
40
|
*
|
|
23
|
-
* //
|
|
24
|
-
* const
|
|
41
|
+
* // 4. Use token with API client for full Developer API access
|
|
42
|
+
* const api = new VybitAPIClient({ accessToken: token.access_token });
|
|
43
|
+
* const vybits = await api.listVybits();
|
|
25
44
|
* ```
|
|
26
45
|
*/
|
|
27
46
|
export declare class VybitOAuth2Client {
|
|
@@ -59,7 +78,7 @@ export declare class VybitOAuth2Client {
|
|
|
59
78
|
*
|
|
60
79
|
* Call this method with the authorization code received from the redirect URI
|
|
61
80
|
* after successful user authorization. The returned access token can be used
|
|
62
|
-
* for
|
|
81
|
+
* with {@link VybitAPIClient} for full Developer API access.
|
|
63
82
|
*
|
|
64
83
|
* @param code - Authorization code from the OAuth2 callback
|
|
65
84
|
* @returns Promise resolving to token response with access token
|
|
@@ -68,21 +87,28 @@ export declare class VybitOAuth2Client {
|
|
|
68
87
|
*
|
|
69
88
|
* @example
|
|
70
89
|
* ```typescript
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
* const
|
|
74
|
-
*
|
|
75
|
-
* if (code) {
|
|
76
|
-
* const token = await client.exchangeCodeForToken(code);
|
|
77
|
-
* console.log('Access token:', token.access_token);
|
|
78
|
-
* }
|
|
90
|
+
* const token = await client.exchangeCodeForToken(authCode);
|
|
91
|
+
* // Use token with API client
|
|
92
|
+
* const api = new VybitAPIClient({ accessToken: token.access_token });
|
|
79
93
|
* ```
|
|
80
94
|
*/
|
|
81
|
-
exchangeCodeForToken(code: string): Promise<TokenResponse>;
|
|
95
|
+
exchangeCodeForToken(code: string, codeVerifier?: string): Promise<TokenResponse>;
|
|
96
|
+
/**
|
|
97
|
+
* Verifies that an access token is valid
|
|
98
|
+
* @param accessToken - Token to verify (uses stored token if not provided)
|
|
99
|
+
* @returns True if the token is valid
|
|
100
|
+
* @throws {VybitAuthError} When no token is available
|
|
101
|
+
*/
|
|
82
102
|
verifyToken(accessToken?: string): Promise<boolean>;
|
|
83
|
-
|
|
84
|
-
|
|
103
|
+
/**
|
|
104
|
+
* Manually sets the access token
|
|
105
|
+
* @param token - The access token to store
|
|
106
|
+
*/
|
|
85
107
|
setAccessToken(token: string): void;
|
|
108
|
+
/**
|
|
109
|
+
* Gets the currently stored access token
|
|
110
|
+
* @returns The stored access token, or undefined if not set
|
|
111
|
+
*/
|
|
86
112
|
getAccessToken(): string | undefined;
|
|
87
113
|
}
|
|
88
114
|
//# sourceMappingURL=oauth2-client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth2-client.d.ts","sourceRoot":"","sources":["../src/oauth2-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,
|
|
1
|
+
{"version":3,"file":"oauth2-client.d.ts","sourceRoot":"","sources":["../src/oauth2-client.ts"],"names":[],"mappings":"AAAA,OAAO,EAQL,YAAY,EACZ,aAAa,EACb,uBAAuB,EACxB,MAAM,aAAa,CAAC;AAErB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,WAAW,CAAC,CAAS;IAE7B;;;;OAIG;gBACS,MAAM,EAAE,YAAY;IAKhC,OAAO,CAAC,cAAc;IAYtB;;;;;;;;;;;;;;;;;;OAkBG;IACH,mBAAmB,CAAC,OAAO,GAAE,uBAA4B,GAAG,MAAM;IAuBlE;;;;;;;;;;;;;;;;;;OAkBG;IACG,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IAkDvF;;;;;OAKG;IACG,WAAW,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IA2BzD;;;OAGG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAInC;;;OAGG;IACH,cAAc,IAAI,MAAM,GAAG,SAAS;CAGrC"}
|
package/dist/oauth2-client.js
CHANGED
|
@@ -3,27 +3,47 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.VybitOAuth2Client = void 0;
|
|
4
4
|
const core_1 = require("@vybit/core");
|
|
5
5
|
/**
|
|
6
|
-
* OAuth2 client for Vybit authentication
|
|
6
|
+
* OAuth2 client for Vybit authentication
|
|
7
7
|
*
|
|
8
|
-
* This client handles the
|
|
9
|
-
*
|
|
8
|
+
* This client handles the OAuth2 authorization flow for Vybit, including
|
|
9
|
+
* authorization URL generation, token exchange, and token verification.
|
|
10
|
+
*
|
|
11
|
+
* Once you have obtained an access token, use {@link VybitAPIClient} from
|
|
12
|
+
* `@vybit/api-sdk` with the `accessToken` option for full Developer API access.
|
|
10
13
|
*
|
|
11
14
|
* @example
|
|
12
15
|
* ```typescript
|
|
13
|
-
*
|
|
16
|
+
* import { VybitOAuth2Client } from '@vybit/oauth2-sdk';
|
|
17
|
+
* import { VybitAPIClient } from '@vybit/api-sdk';
|
|
18
|
+
*
|
|
19
|
+
* // 1. Set up OAuth2 client
|
|
20
|
+
* const oauth = new VybitOAuth2Client({
|
|
14
21
|
* clientId: 'your-client-id',
|
|
15
22
|
* clientSecret: 'your-client-secret',
|
|
16
23
|
* redirectUri: 'https://yourapp.com/oauth/callback'
|
|
17
24
|
* });
|
|
18
25
|
*
|
|
19
|
-
* // Generate authorization URL
|
|
20
|
-
* const authUrl =
|
|
26
|
+
* // 2. Generate authorization URL and redirect user
|
|
27
|
+
* const authUrl = oauth.getAuthorizationUrl();
|
|
28
|
+
*
|
|
29
|
+
* // 3. Exchange authorization code for token (in callback handler)
|
|
30
|
+
* const token = await oauth.exchangeCodeForToken(authCode);
|
|
31
|
+
*
|
|
32
|
+
* // --- PKCE flow (public clients, no client_secret needed) ---
|
|
33
|
+
* import { generateCodeVerifier, generateCodeChallenge } from '@vybit/core';
|
|
21
34
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
35
|
+
* const pkceClient = new VybitOAuth2Client({
|
|
36
|
+
* clientId: 'your-client-id',
|
|
37
|
+
* redirectUri: 'https://yourapp.com/oauth/callback'
|
|
38
|
+
* });
|
|
39
|
+
* const verifier = generateCodeVerifier();
|
|
40
|
+
* const challenge = await generateCodeChallenge(verifier);
|
|
41
|
+
* const pkceAuthUrl = pkceClient.getAuthorizationUrl({ codeChallenge: challenge });
|
|
42
|
+
* const pkceToken = await pkceClient.exchangeCodeForToken(authCode, verifier);
|
|
24
43
|
*
|
|
25
|
-
* //
|
|
26
|
-
* const
|
|
44
|
+
* // 4. Use token with API client for full Developer API access
|
|
45
|
+
* const api = new VybitAPIClient({ accessToken: token.access_token });
|
|
46
|
+
* const vybits = await api.listVybits();
|
|
27
47
|
* ```
|
|
28
48
|
*/
|
|
29
49
|
class VybitOAuth2Client {
|
|
@@ -40,9 +60,6 @@ class VybitOAuth2Client {
|
|
|
40
60
|
if (!config.clientId) {
|
|
41
61
|
throw new core_1.VybitValidationError('Client ID is required');
|
|
42
62
|
}
|
|
43
|
-
if (!config.clientSecret) {
|
|
44
|
-
throw new core_1.VybitValidationError('Client Secret is required');
|
|
45
|
-
}
|
|
46
63
|
if (!config.redirectUri) {
|
|
47
64
|
throw new core_1.VybitValidationError('Redirect URI is required');
|
|
48
65
|
}
|
|
@@ -81,6 +98,10 @@ class VybitOAuth2Client {
|
|
|
81
98
|
if (options.scope) {
|
|
82
99
|
params.append('scope', options.scope);
|
|
83
100
|
}
|
|
101
|
+
if (options.codeChallenge) {
|
|
102
|
+
params.append('code_challenge', options.codeChallenge);
|
|
103
|
+
params.append('code_challenge_method', options.codeChallengeMethod || 'S256');
|
|
104
|
+
}
|
|
84
105
|
return `${authDomain}?${params.toString()}`;
|
|
85
106
|
}
|
|
86
107
|
/**
|
|
@@ -88,7 +109,7 @@ class VybitOAuth2Client {
|
|
|
88
109
|
*
|
|
89
110
|
* Call this method with the authorization code received from the redirect URI
|
|
90
111
|
* after successful user authorization. The returned access token can be used
|
|
91
|
-
* for
|
|
112
|
+
* with {@link VybitAPIClient} for full Developer API access.
|
|
92
113
|
*
|
|
93
114
|
* @param code - Authorization code from the OAuth2 callback
|
|
94
115
|
* @returns Promise resolving to token response with access token
|
|
@@ -97,25 +118,25 @@ class VybitOAuth2Client {
|
|
|
97
118
|
*
|
|
98
119
|
* @example
|
|
99
120
|
* ```typescript
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
* const
|
|
103
|
-
*
|
|
104
|
-
* if (code) {
|
|
105
|
-
* const token = await client.exchangeCodeForToken(code);
|
|
106
|
-
* console.log('Access token:', token.access_token);
|
|
107
|
-
* }
|
|
121
|
+
* const token = await client.exchangeCodeForToken(authCode);
|
|
122
|
+
* // Use token with API client
|
|
123
|
+
* const api = new VybitAPIClient({ accessToken: token.access_token });
|
|
108
124
|
* ```
|
|
109
125
|
*/
|
|
110
|
-
async exchangeCodeForToken(code) {
|
|
126
|
+
async exchangeCodeForToken(code, codeVerifier) {
|
|
111
127
|
const authDomain = (0, core_1.getAuthDomain)();
|
|
112
128
|
const tokenUrl = `${authDomain}/service/token`;
|
|
113
129
|
const formData = new URLSearchParams({
|
|
114
130
|
grant_type: 'authorization_code',
|
|
115
131
|
code,
|
|
116
132
|
client_id: this.config.clientId,
|
|
117
|
-
client_secret: this.config.clientSecret,
|
|
118
133
|
});
|
|
134
|
+
if (this.config.clientSecret) {
|
|
135
|
+
formData.append('client_secret', this.config.clientSecret);
|
|
136
|
+
}
|
|
137
|
+
if (codeVerifier) {
|
|
138
|
+
formData.append('code_verifier', codeVerifier);
|
|
139
|
+
}
|
|
119
140
|
try {
|
|
120
141
|
const response = await fetch(tokenUrl, {
|
|
121
142
|
method: 'POST',
|
|
@@ -141,6 +162,12 @@ class VybitOAuth2Client {
|
|
|
141
162
|
throw new core_1.VybitAPIError(`Network error during token exchange: ${error}`);
|
|
142
163
|
}
|
|
143
164
|
}
|
|
165
|
+
/**
|
|
166
|
+
* Verifies that an access token is valid
|
|
167
|
+
* @param accessToken - Token to verify (uses stored token if not provided)
|
|
168
|
+
* @returns True if the token is valid
|
|
169
|
+
* @throws {VybitAuthError} When no token is available
|
|
170
|
+
*/
|
|
144
171
|
async verifyToken(accessToken) {
|
|
145
172
|
const token = accessToken || this.accessToken;
|
|
146
173
|
if (!token) {
|
|
@@ -164,81 +191,17 @@ class VybitOAuth2Client {
|
|
|
164
191
|
return false;
|
|
165
192
|
}
|
|
166
193
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
const baseUrl = (0, core_1.getDefaultBaseUrl)();
|
|
173
|
-
const listUrl = `${baseUrl}/rest/vybit_list`;
|
|
174
|
-
try {
|
|
175
|
-
const response = await fetch(listUrl, {
|
|
176
|
-
headers: {
|
|
177
|
-
Authorization: `Bearer ${token}`,
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
if (!response.ok) {
|
|
181
|
-
throw new core_1.VybitAPIError(`Failed to fetch vybit list: ${response.statusText}`, response.status);
|
|
182
|
-
}
|
|
183
|
-
const data = await response.json();
|
|
184
|
-
// Convert object with numeric keys to array
|
|
185
|
-
return Object.values(data);
|
|
186
|
-
}
|
|
187
|
-
catch (error) {
|
|
188
|
-
if (error instanceof core_1.VybitAPIError) {
|
|
189
|
-
throw error;
|
|
190
|
-
}
|
|
191
|
-
throw new core_1.VybitAPIError(`Network error fetching vybit list: ${error}`);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
async sendVybitNotification(triggerKey, options = {}, accessToken) {
|
|
195
|
-
const token = accessToken || this.accessToken;
|
|
196
|
-
if (!token) {
|
|
197
|
-
throw new core_1.VybitAuthError('No access token available');
|
|
198
|
-
}
|
|
199
|
-
// Validate URL parameters
|
|
200
|
-
if (options.imageUrl && !(0, core_1.isValidUrl)(options.imageUrl)) {
|
|
201
|
-
throw new core_1.VybitValidationError('Image URL must be a valid URL');
|
|
202
|
-
}
|
|
203
|
-
if (options.linkUrl && !(0, core_1.isValidUrl)(options.linkUrl)) {
|
|
204
|
-
throw new core_1.VybitValidationError('Link URL must be a valid URL');
|
|
205
|
-
}
|
|
206
|
-
const baseUrl = (0, core_1.getDefaultBaseUrl)();
|
|
207
|
-
const triggerUrl = `${baseUrl}/fire/${triggerKey}`;
|
|
208
|
-
// Build payload
|
|
209
|
-
const payload = {};
|
|
210
|
-
if (options.message)
|
|
211
|
-
payload.message = options.message;
|
|
212
|
-
if (options.imageUrl)
|
|
213
|
-
payload.imageUrl = options.imageUrl;
|
|
214
|
-
if (options.linkUrl)
|
|
215
|
-
payload.linkUrl = options.linkUrl;
|
|
216
|
-
if (options.log)
|
|
217
|
-
payload.log = options.log;
|
|
218
|
-
try {
|
|
219
|
-
const response = await fetch(triggerUrl, {
|
|
220
|
-
method: 'POST',
|
|
221
|
-
headers: {
|
|
222
|
-
Authorization: `Bearer ${token}`,
|
|
223
|
-
'Content-Type': 'application/json',
|
|
224
|
-
},
|
|
225
|
-
body: JSON.stringify(payload),
|
|
226
|
-
});
|
|
227
|
-
if (!response.ok) {
|
|
228
|
-
throw new core_1.VybitAPIError(`Failed to send vybit notification: ${response.statusText}`, response.status);
|
|
229
|
-
}
|
|
230
|
-
return await response.json();
|
|
231
|
-
}
|
|
232
|
-
catch (error) {
|
|
233
|
-
if (error instanceof core_1.VybitAPIError) {
|
|
234
|
-
throw error;
|
|
235
|
-
}
|
|
236
|
-
throw new core_1.VybitAPIError(`Network error sending notification: ${error}`);
|
|
237
|
-
}
|
|
238
|
-
}
|
|
194
|
+
/**
|
|
195
|
+
* Manually sets the access token
|
|
196
|
+
* @param token - The access token to store
|
|
197
|
+
*/
|
|
239
198
|
setAccessToken(token) {
|
|
240
199
|
this.accessToken = token;
|
|
241
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Gets the currently stored access token
|
|
203
|
+
* @returns The stored access token, or undefined if not set
|
|
204
|
+
*/
|
|
242
205
|
getAccessToken() {
|
|
243
206
|
return this.accessToken;
|
|
244
207
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth2-client.js","sourceRoot":"","sources":["../src/oauth2-client.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"oauth2-client.js","sourceRoot":"","sources":["../src/oauth2-client.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,58 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Re-export all types from @vybit/core for backward compatibility.
|
|
3
|
+
* Types are maintained in the core package as the single source of truth.
|
|
3
4
|
*/
|
|
4
|
-
export
|
|
5
|
-
/** OAuth2 client ID from your Vybit developer account */
|
|
6
|
-
clientId: string;
|
|
7
|
-
/** OAuth2 client secret from your Vybit developer account */
|
|
8
|
-
clientSecret: string;
|
|
9
|
-
/** Redirect URI that matches your Vybit app configuration */
|
|
10
|
-
redirectUri: string;
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* OAuth2 token response from successful authentication
|
|
14
|
-
*/
|
|
15
|
-
export interface TokenResponse {
|
|
16
|
-
/** Access token for authenticated API calls */
|
|
17
|
-
access_token: string;
|
|
18
|
-
/** Token type (typically "Bearer") */
|
|
19
|
-
token_type: string;
|
|
20
|
-
/** Token expiration time in seconds (optional) */
|
|
21
|
-
expires_in?: number;
|
|
22
|
-
/** Refresh token for token renewal (optional) */
|
|
23
|
-
refresh_token?: string;
|
|
24
|
-
/** Granted scopes for this token (optional) */
|
|
25
|
-
scope?: string;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Options for generating OAuth2 authorization URLs
|
|
29
|
-
*/
|
|
30
|
-
export interface AuthorizationUrlOptions {
|
|
31
|
-
/** Custom state parameter for security (auto-generated if not provided) */
|
|
32
|
-
state?: string;
|
|
33
|
-
/** Requested OAuth2 scopes (space-separated) */
|
|
34
|
-
scope?: string;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Options for triggering vybit notifications
|
|
38
|
-
*/
|
|
39
|
-
export interface TriggerOptions {
|
|
40
|
-
/** Custom message text for the notification */
|
|
41
|
-
message?: string;
|
|
42
|
-
/** URL to an image to display with the notification (must be a direct link to a JPG, PNG, or GIF image) */
|
|
43
|
-
imageUrl?: string;
|
|
44
|
-
/** URL to open when the notification is clicked */
|
|
45
|
-
linkUrl?: string;
|
|
46
|
-
/** Custom log message for debugging */
|
|
47
|
-
log?: string;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Response from triggering a vybit notification
|
|
51
|
-
*/
|
|
52
|
-
export interface TriggerResponse {
|
|
53
|
-
/** Result code (1 = success) */
|
|
54
|
-
result: number;
|
|
55
|
-
/** Processing key for tracking the notification */
|
|
56
|
-
plk: string;
|
|
57
|
-
}
|
|
5
|
+
export * from '@vybit/core';
|
|
58
6
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,cAAc,aAAa,CAAC"}
|
package/dist/types.js
CHANGED
|
@@ -1,3 +1,22 @@
|
|
|
1
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 __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
2
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/**
|
|
18
|
+
* Re-export all types from @vybit/core for backward compatibility.
|
|
19
|
+
* Types are maintained in the core package as the single source of truth.
|
|
20
|
+
*/
|
|
21
|
+
__exportStar(require("@vybit/core"), exports);
|
|
3
22
|
//# sourceMappingURL=types.js.map
|
package/dist/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA;;;GAGG;AACH,8CAA4B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vybit/oauth2-sdk",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "OAuth 2.0 SDK for Vybit authentication and authorization",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"node": ">=16.0.0"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@vybit/core": "^1.
|
|
42
|
+
"@vybit/core": "^1.3.0"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
45
|
"node-fetch": "^3.0.0"
|