@bernierllc/dropbox-oauth 0.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/LICENSE +7 -0
- package/README.md +168 -0
- package/dist/DropboxOAuth.d.ts +83 -0
- package/dist/DropboxOAuth.d.ts.map +1 -0
- package/dist/DropboxOAuth.js +228 -0
- package/dist/DropboxOAuth.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +55 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright (c) 2025 Bernier LLC
|
|
2
|
+
|
|
3
|
+
This file is licensed to the client under a limited-use license.
|
|
4
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
5
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
6
|
+
|
|
7
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# @bernierllc/dropbox-oauth
|
|
2
|
+
|
|
3
|
+
OAuth 2.0 authentication and token management for Dropbox.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- OAuth 2.0 authorization URL generation with PKCE
|
|
8
|
+
- Authorization code exchange for access tokens
|
|
9
|
+
- Automatic token refresh with refresh tokens
|
|
10
|
+
- Token validation and expiration checking
|
|
11
|
+
- Secure credential storage interfaces
|
|
12
|
+
- Multi-user token management
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @bernierllc/dropbox-oauth
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### Basic Authentication Flow
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { DropboxOAuth } from '@bernierllc/dropbox-oauth';
|
|
26
|
+
|
|
27
|
+
// Create auth instance
|
|
28
|
+
const dropboxAuth = new DropboxOAuth({
|
|
29
|
+
clientId: 'your-client-id',
|
|
30
|
+
clientSecret: 'your-client-secret',
|
|
31
|
+
redirectUri: 'https://your-app.com/oauth/dropbox/callback'
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Step 1: Generate authorization URL
|
|
35
|
+
const { url, state } = dropboxAuth.getAuthorizationUrl();
|
|
36
|
+
// Store state in session for CSRF protection
|
|
37
|
+
// Redirect user to url
|
|
38
|
+
|
|
39
|
+
// Step 2: Exchange authorization code for tokens
|
|
40
|
+
const tokens = await dropboxAuth.exchangeCodeForTokens(code, state);
|
|
41
|
+
console.log('Access token:', tokens.accessToken);
|
|
42
|
+
console.log('Refresh token:', tokens.refreshToken);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Token Refresh
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
// Manually refresh token
|
|
49
|
+
const newTokens = await dropboxAuth.refreshAccessToken(refreshToken);
|
|
50
|
+
|
|
51
|
+
// Or use automatic refresh with storage
|
|
52
|
+
const storage: TokenStorage = {
|
|
53
|
+
async store(key, tokens) {
|
|
54
|
+
// Store tokens in your database
|
|
55
|
+
await db.saveTokens(key, tokens);
|
|
56
|
+
},
|
|
57
|
+
async retrieve(key) {
|
|
58
|
+
// Retrieve tokens from your database
|
|
59
|
+
return await db.getTokens(key);
|
|
60
|
+
},
|
|
61
|
+
async delete(key) {
|
|
62
|
+
// Delete tokens from your database
|
|
63
|
+
await db.deleteTokens(key);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const authWithStorage = new DropboxOAuth(config, storage);
|
|
68
|
+
|
|
69
|
+
// Automatically refreshes if token is expired
|
|
70
|
+
const validToken = await authWithStorage.getValidToken('user-123');
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Token Validation
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
const isValid = await dropboxAuth.validateToken(accessToken);
|
|
77
|
+
if (!isValid) {
|
|
78
|
+
console.log('Token is invalid or expired');
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## API
|
|
83
|
+
|
|
84
|
+
### `DropboxOAuth`
|
|
85
|
+
|
|
86
|
+
#### Constructor
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
constructor(config: DropboxOAuthConfig, storage?: TokenStorage)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- `config.clientId` - Dropbox app client ID
|
|
93
|
+
- `config.clientSecret` - Dropbox app client secret
|
|
94
|
+
- `config.redirectUri` - OAuth redirect URI
|
|
95
|
+
- `config.logger` - (Optional) Custom logger instance
|
|
96
|
+
- `storage` - (Optional) Token storage implementation
|
|
97
|
+
|
|
98
|
+
#### Methods
|
|
99
|
+
|
|
100
|
+
##### `getAuthorizationUrl(state?: string, scopes?: string[]): { url: string; state: string }`
|
|
101
|
+
|
|
102
|
+
Generate OAuth authorization URL with PKCE.
|
|
103
|
+
|
|
104
|
+
##### `exchangeCodeForTokens(code: string, state: string): Promise<DropboxOAuthTokens>`
|
|
105
|
+
|
|
106
|
+
Exchange authorization code for access and refresh tokens.
|
|
107
|
+
|
|
108
|
+
##### `refreshAccessToken(refreshToken: string): Promise<DropboxOAuthTokens>`
|
|
109
|
+
|
|
110
|
+
Refresh access token using refresh token.
|
|
111
|
+
|
|
112
|
+
##### `validateToken(accessToken: string): Promise<boolean>`
|
|
113
|
+
|
|
114
|
+
Validate access token against Dropbox API.
|
|
115
|
+
|
|
116
|
+
##### `getValidToken(storageKey: string): Promise<string>`
|
|
117
|
+
|
|
118
|
+
Get a valid access token, automatically refreshing if expired (requires storage).
|
|
119
|
+
|
|
120
|
+
##### `storeTokens(key: string, tokens: DropboxOAuthTokens): Promise<void>`
|
|
121
|
+
|
|
122
|
+
Store tokens (requires storage).
|
|
123
|
+
|
|
124
|
+
##### `revokeTokens(storageKey: string): Promise<void>`
|
|
125
|
+
|
|
126
|
+
Revoke and delete tokens (requires storage).
|
|
127
|
+
|
|
128
|
+
### `TokenStorage` Interface
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
interface TokenStorage {
|
|
132
|
+
store(key: string, tokens: DropboxOAuthTokens): Promise<void>;
|
|
133
|
+
retrieve(key: string): Promise<DropboxOAuthTokens | null>;
|
|
134
|
+
delete(key: string): Promise<void>;
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Implement this interface to provide persistent token storage.
|
|
139
|
+
|
|
140
|
+
## Token Expiration
|
|
141
|
+
|
|
142
|
+
Tokens are automatically refreshed when:
|
|
143
|
+
- Less than 5 minutes remaining before expiration
|
|
144
|
+
- `getValidToken()` is called with valid refresh token
|
|
145
|
+
|
|
146
|
+
## Error Handling
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
try {
|
|
150
|
+
const tokens = await dropboxAuth.exchangeCodeForTokens(code, state);
|
|
151
|
+
} catch (error) {
|
|
152
|
+
console.error('OAuth failed:', error.message);
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
All methods throw descriptive errors on failure.
|
|
157
|
+
|
|
158
|
+
## Integration
|
|
159
|
+
|
|
160
|
+
### Logger Integration
|
|
161
|
+
|
|
162
|
+
This package uses `@bernierllc/logger` for structured logging. The logger is optional and will use a no-op logger if not provided.
|
|
163
|
+
|
|
164
|
+
## License
|
|
165
|
+
|
|
166
|
+
Copyright (c) 2025 Bernier LLC. See LICENSE file for details.
|
|
167
|
+
|
|
168
|
+
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Logger } from "@bernierllc/logger";
|
|
2
|
+
import { DropboxOAuthConfig, DropboxOAuthTokens, TokenStorage } from "./types";
|
|
3
|
+
/**
|
|
4
|
+
* Extended configuration including logger
|
|
5
|
+
*/
|
|
6
|
+
export interface DropboxOAuthConfigWithLogger extends DropboxOAuthConfig {
|
|
7
|
+
logger?: Logger;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* DropboxOAuth - OAuth 2.0 authentication and token management for Dropbox
|
|
11
|
+
*
|
|
12
|
+
* Handles:
|
|
13
|
+
* - Authorization URL generation with PKCE
|
|
14
|
+
* - Authorization code exchange
|
|
15
|
+
* - Token refresh
|
|
16
|
+
* - Token validation
|
|
17
|
+
* - Automatic token refresh with storage
|
|
18
|
+
*/
|
|
19
|
+
export declare class DropboxOAuth {
|
|
20
|
+
private config;
|
|
21
|
+
private logger;
|
|
22
|
+
private storage;
|
|
23
|
+
private auth;
|
|
24
|
+
/**
|
|
25
|
+
* Create a new DropboxOAuth instance
|
|
26
|
+
* @param config - OAuth configuration
|
|
27
|
+
* @param storage - Optional token storage for automatic refresh
|
|
28
|
+
*/
|
|
29
|
+
constructor(config: DropboxOAuthConfigWithLogger, storage?: TokenStorage);
|
|
30
|
+
/**
|
|
31
|
+
* Generate OAuth authorization URL with PKCE
|
|
32
|
+
* @param state - Optional state parameter for CSRF protection (auto-generated if not provided)
|
|
33
|
+
* @param scopes - Requested Dropbox scopes (default: ['files.content.write', 'files.content.read'])
|
|
34
|
+
* @returns Object with authorization URL and state
|
|
35
|
+
*/
|
|
36
|
+
getAuthorizationUrl(state?: string, scopes?: string[]): {
|
|
37
|
+
url: string;
|
|
38
|
+
state: string;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Exchange authorization code for access and refresh tokens
|
|
42
|
+
* @param code - Authorization code from OAuth callback
|
|
43
|
+
* @param state - State token for CSRF validation
|
|
44
|
+
* @returns OAuth tokens
|
|
45
|
+
* @throws Error if exchange fails
|
|
46
|
+
*/
|
|
47
|
+
exchangeCodeForTokens(code: string, _state: string): Promise<DropboxOAuthTokens>;
|
|
48
|
+
/**
|
|
49
|
+
* Refresh access token using refresh token
|
|
50
|
+
* @param refreshToken - Refresh token
|
|
51
|
+
* @returns New OAuth tokens
|
|
52
|
+
* @throws Error if refresh fails
|
|
53
|
+
*/
|
|
54
|
+
refreshAccessToken(refreshToken: string): DropboxOAuthTokens;
|
|
55
|
+
/**
|
|
56
|
+
* Validate access token by making a test request to Dropbox API
|
|
57
|
+
* @param accessToken - Access token to validate
|
|
58
|
+
* @returns True if token is valid, false otherwise
|
|
59
|
+
*/
|
|
60
|
+
validateToken(accessToken: string): Promise<boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* Get a valid access token, automatically refreshing if expired
|
|
63
|
+
* Requires storage to be configured
|
|
64
|
+
* @param storageKey - Key to retrieve tokens from storage
|
|
65
|
+
* @returns Valid access token
|
|
66
|
+
* @throws Error if storage not configured or tokens not found
|
|
67
|
+
*/
|
|
68
|
+
getValidToken(storageKey: string): Promise<string>;
|
|
69
|
+
/**
|
|
70
|
+
* Store tokens using configured storage
|
|
71
|
+
* @param key - Storage key
|
|
72
|
+
* @param tokens - Tokens to store
|
|
73
|
+
* @throws Error if storage not configured
|
|
74
|
+
*/
|
|
75
|
+
storeTokens(key: string, tokens: DropboxOAuthTokens): Promise<void>;
|
|
76
|
+
/**
|
|
77
|
+
* Revoke and delete tokens from storage
|
|
78
|
+
* @param storageKey - Storage key
|
|
79
|
+
* @throws Error if storage not configured
|
|
80
|
+
*/
|
|
81
|
+
revokeTokens(storageKey: string): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=DropboxOAuth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DropboxOAuth.d.ts","sourceRoot":"","sources":["../src/DropboxOAuth.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,MAAM,EAAgB,MAAM,oBAAoB,CAAC;AAG1D,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EAEb,MAAM,SAAS,CAAC;AAEjB;;GAEG;AACH,MAAM,WAAW,4BAA6B,SAAQ,kBAAkB;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;GASG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,IAAI,CAAc;IAE1B;;;;OAIG;gBACS,MAAM,EAAE,4BAA4B,EAAE,OAAO,CAAC,EAAE,YAAY;IAwBxE;;;;;OAKG;IACH,mBAAmB,CACjB,KAAK,CAAC,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EAAE,GAChB;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IA+BjC;;;;;;OAMG;IACG,qBAAqB,CACzB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,kBAAkB,CAAC;IAyC9B;;;;;OAKG;IACH,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB;IAwC5D;;;;OAIG;IACG,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAc1D;;;;;;OAMG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA0BxD;;;;;OAKG;IACG,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IASzE;;;;OAIG;IACG,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQtD"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.DropboxOAuth = void 0;
|
|
11
|
+
const logger_1 = require("@bernierllc/logger");
|
|
12
|
+
const dropbox_1 = require("dropbox");
|
|
13
|
+
const uuid_1 = require("uuid");
|
|
14
|
+
/**
|
|
15
|
+
* DropboxOAuth - OAuth 2.0 authentication and token management for Dropbox
|
|
16
|
+
*
|
|
17
|
+
* Handles:
|
|
18
|
+
* - Authorization URL generation with PKCE
|
|
19
|
+
* - Authorization code exchange
|
|
20
|
+
* - Token refresh
|
|
21
|
+
* - Token validation
|
|
22
|
+
* - Automatic token refresh with storage
|
|
23
|
+
*/
|
|
24
|
+
class DropboxOAuth {
|
|
25
|
+
/**
|
|
26
|
+
* Create a new DropboxOAuth instance
|
|
27
|
+
* @param config - OAuth configuration
|
|
28
|
+
* @param storage - Optional token storage for automatic refresh
|
|
29
|
+
*/
|
|
30
|
+
constructor(config, storage) {
|
|
31
|
+
this.config = {
|
|
32
|
+
clientId: config.clientId,
|
|
33
|
+
clientSecret: config.clientSecret,
|
|
34
|
+
redirectUri: config.redirectUri,
|
|
35
|
+
};
|
|
36
|
+
this.logger =
|
|
37
|
+
config.logger ||
|
|
38
|
+
(0, logger_1.createLogger)({
|
|
39
|
+
context: {
|
|
40
|
+
service: "DropboxOAuth",
|
|
41
|
+
version: "0.1.0",
|
|
42
|
+
environment: process.env.NODE_ENV || "development",
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
this.storage = storage;
|
|
46
|
+
// Initialize DropboxAuth
|
|
47
|
+
this.auth = new dropbox_1.DropboxAuth({
|
|
48
|
+
clientId: this.config.clientId,
|
|
49
|
+
clientSecret: this.config.clientSecret,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Generate OAuth authorization URL with PKCE
|
|
54
|
+
* @param state - Optional state parameter for CSRF protection (auto-generated if not provided)
|
|
55
|
+
* @param scopes - Requested Dropbox scopes (default: ['files.content.write', 'files.content.read'])
|
|
56
|
+
* @returns Object with authorization URL and state
|
|
57
|
+
*/
|
|
58
|
+
getAuthorizationUrl(state, scopes) {
|
|
59
|
+
const authState = state || (0, uuid_1.v4)();
|
|
60
|
+
const requestedScopes = scopes || [
|
|
61
|
+
"files.content.write",
|
|
62
|
+
"files.content.read",
|
|
63
|
+
"account_info.read",
|
|
64
|
+
];
|
|
65
|
+
// Dropbox uses PKCE, so we need to get the auth URL from the SDK
|
|
66
|
+
// getAuthenticationUrl returns a string synchronously
|
|
67
|
+
const authUrl = this.auth.getAuthenticationUrl(this.config.redirectUri, authState, "code", "offline", requestedScopes, "none", false);
|
|
68
|
+
this.logger.info("Authorization URL generated", {
|
|
69
|
+
state: authState,
|
|
70
|
+
scopes: requestedScopes,
|
|
71
|
+
});
|
|
72
|
+
return {
|
|
73
|
+
url: authUrl,
|
|
74
|
+
state: authState,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Exchange authorization code for access and refresh tokens
|
|
79
|
+
* @param code - Authorization code from OAuth callback
|
|
80
|
+
* @param state - State token for CSRF validation
|
|
81
|
+
* @returns OAuth tokens
|
|
82
|
+
* @throws Error if exchange fails
|
|
83
|
+
*/
|
|
84
|
+
async exchangeCodeForTokens(code, _state) {
|
|
85
|
+
try {
|
|
86
|
+
// Dropbox SDK handles the token exchange
|
|
87
|
+
const tokenResult = await this.auth.getAccessTokenFromCode(this.config.redirectUri, code);
|
|
88
|
+
if (!tokenResult.result) {
|
|
89
|
+
throw new Error("No token result from Dropbox");
|
|
90
|
+
}
|
|
91
|
+
const result = tokenResult.result;
|
|
92
|
+
const tokens = {
|
|
93
|
+
accessToken: result.access_token,
|
|
94
|
+
refreshToken: result.refresh_token ?? undefined,
|
|
95
|
+
expiresAt: result.expires_in
|
|
96
|
+
? new Date(Date.now() + result.expires_in * 1000)
|
|
97
|
+
: undefined,
|
|
98
|
+
tokenType: result.token_type ?? "bearer",
|
|
99
|
+
scope: result.scope ?? undefined,
|
|
100
|
+
accountId: result.account_id ?? undefined,
|
|
101
|
+
};
|
|
102
|
+
this.logger.info("OAuth tokens obtained", {
|
|
103
|
+
hasRefreshToken: !!tokens.refreshToken,
|
|
104
|
+
expiresAt: tokens.expiresAt,
|
|
105
|
+
accountId: tokens.accountId,
|
|
106
|
+
});
|
|
107
|
+
return tokens;
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
111
|
+
this.logger.error("Failed to exchange code for tokens", undefined, {
|
|
112
|
+
errorMessage,
|
|
113
|
+
});
|
|
114
|
+
throw new Error(`OAuth token exchange failed: ${errorMessage}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Refresh access token using refresh token
|
|
119
|
+
* @param refreshToken - Refresh token
|
|
120
|
+
* @returns New OAuth tokens
|
|
121
|
+
* @throws Error if refresh fails
|
|
122
|
+
*/
|
|
123
|
+
refreshAccessToken(refreshToken) {
|
|
124
|
+
try {
|
|
125
|
+
// Set the refresh token in the auth instance
|
|
126
|
+
this.auth.setRefreshToken(refreshToken);
|
|
127
|
+
// Refresh access token - this updates the internal state
|
|
128
|
+
// Note: refreshAccessToken() returns void but is synchronous
|
|
129
|
+
this.auth.refreshAccessToken();
|
|
130
|
+
// Get the access token from the auth instance
|
|
131
|
+
const accessToken = this.auth.getAccessToken();
|
|
132
|
+
if (!accessToken) {
|
|
133
|
+
throw new Error("No access token after refresh");
|
|
134
|
+
}
|
|
135
|
+
// Dropbox refresh doesn't return expiry, so we'll set a default
|
|
136
|
+
// Access tokens typically last 4 hours
|
|
137
|
+
const tokens = {
|
|
138
|
+
accessToken: accessToken,
|
|
139
|
+
refreshToken: refreshToken || undefined, // Keep existing refresh token
|
|
140
|
+
expiresAt: new Date(Date.now() + 4 * 60 * 60 * 1000), // 4 hours default
|
|
141
|
+
tokenType: "bearer",
|
|
142
|
+
scope: undefined,
|
|
143
|
+
};
|
|
144
|
+
this.logger.info("Access token refreshed", {
|
|
145
|
+
expiresAt: tokens.expiresAt,
|
|
146
|
+
});
|
|
147
|
+
return tokens;
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
151
|
+
this.logger.error("Failed to refresh access token", undefined, {
|
|
152
|
+
errorMessage,
|
|
153
|
+
});
|
|
154
|
+
throw new Error(`Token refresh failed: ${errorMessage}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Validate access token by making a test request to Dropbox API
|
|
159
|
+
* @param accessToken - Access token to validate
|
|
160
|
+
* @returns True if token is valid, false otherwise
|
|
161
|
+
*/
|
|
162
|
+
async validateToken(accessToken) {
|
|
163
|
+
try {
|
|
164
|
+
const dbx = new dropbox_1.Dropbox({ accessToken });
|
|
165
|
+
const response = await dbx.usersGetCurrentAccount();
|
|
166
|
+
return !!response.result;
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
this.logger.warn("Token validation failed", {
|
|
170
|
+
error: error instanceof Error ? error.message : "Unknown error",
|
|
171
|
+
});
|
|
172
|
+
return false;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Get a valid access token, automatically refreshing if expired
|
|
177
|
+
* Requires storage to be configured
|
|
178
|
+
* @param storageKey - Key to retrieve tokens from storage
|
|
179
|
+
* @returns Valid access token
|
|
180
|
+
* @throws Error if storage not configured or tokens not found
|
|
181
|
+
*/
|
|
182
|
+
async getValidToken(storageKey) {
|
|
183
|
+
if (!this.storage) {
|
|
184
|
+
throw new Error("Token storage not configured");
|
|
185
|
+
}
|
|
186
|
+
const tokens = await this.storage.retrieve(storageKey);
|
|
187
|
+
if (!tokens) {
|
|
188
|
+
throw new Error("No tokens found in storage");
|
|
189
|
+
}
|
|
190
|
+
// Check if token is expired (with 5 minute buffer)
|
|
191
|
+
const isExpiring = tokens.expiresAt &&
|
|
192
|
+
tokens.expiresAt.getTime() - Date.now() < 5 * 60 * 1000;
|
|
193
|
+
if (isExpiring && tokens.refreshToken) {
|
|
194
|
+
this.logger.info("Token expiring, refreshing...", { storageKey });
|
|
195
|
+
const newTokens = this.refreshAccessToken(tokens.refreshToken);
|
|
196
|
+
await this.storage.store(storageKey, newTokens);
|
|
197
|
+
return newTokens.accessToken;
|
|
198
|
+
}
|
|
199
|
+
return tokens.accessToken;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Store tokens using configured storage
|
|
203
|
+
* @param key - Storage key
|
|
204
|
+
* @param tokens - Tokens to store
|
|
205
|
+
* @throws Error if storage not configured
|
|
206
|
+
*/
|
|
207
|
+
async storeTokens(key, tokens) {
|
|
208
|
+
if (!this.storage) {
|
|
209
|
+
throw new Error("Token storage not configured");
|
|
210
|
+
}
|
|
211
|
+
await this.storage.store(key, tokens);
|
|
212
|
+
this.logger.info("Tokens stored", { key });
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Revoke and delete tokens from storage
|
|
216
|
+
* @param storageKey - Storage key
|
|
217
|
+
* @throws Error if storage not configured
|
|
218
|
+
*/
|
|
219
|
+
async revokeTokens(storageKey) {
|
|
220
|
+
if (!this.storage) {
|
|
221
|
+
throw new Error("Token storage not configured");
|
|
222
|
+
}
|
|
223
|
+
await this.storage.delete(storageKey);
|
|
224
|
+
this.logger.info("Tokens revoked", { storageKey });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
exports.DropboxOAuth = DropboxOAuth;
|
|
228
|
+
//# sourceMappingURL=DropboxOAuth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DropboxOAuth.js","sourceRoot":"","sources":["../src/DropboxOAuth.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,YAAY,EACZ,KAAK,4BAA4B,GAClC,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,GACb,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.DropboxOAuth = void 0;
|
|
11
|
+
var DropboxOAuth_1 = require("./DropboxOAuth");
|
|
12
|
+
Object.defineProperty(exports, "DropboxOAuth", { enumerable: true, get: function () { return DropboxOAuth_1.DropboxOAuth; } });
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;EAME;;;AAEF,+CAGwB;AAFtB,4GAAA,YAAY,OAAA"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth 2.0 tokens returned by Dropbox
|
|
3
|
+
*/
|
|
4
|
+
export interface DropboxOAuthTokens {
|
|
5
|
+
accessToken: string;
|
|
6
|
+
refreshToken?: string | undefined;
|
|
7
|
+
expiresAt?: Date | undefined;
|
|
8
|
+
tokenType: string;
|
|
9
|
+
scope?: string | undefined;
|
|
10
|
+
accountId?: string | undefined;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* OAuth 2.0 configuration for Dropbox
|
|
14
|
+
*/
|
|
15
|
+
export interface DropboxOAuthConfig {
|
|
16
|
+
clientId: string;
|
|
17
|
+
clientSecret: string;
|
|
18
|
+
redirectUri: string;
|
|
19
|
+
logger?: import("@bernierllc/logger").Logger;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Token storage interface for persistent credential management
|
|
23
|
+
*/
|
|
24
|
+
export interface TokenStorage {
|
|
25
|
+
/**
|
|
26
|
+
* Store OAuth tokens
|
|
27
|
+
* @param key - Storage key (e.g., user ID)
|
|
28
|
+
* @param tokens - OAuth tokens to store
|
|
29
|
+
*/
|
|
30
|
+
store(_key: string, _tokens: DropboxOAuthTokens): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Retrieve OAuth tokens
|
|
33
|
+
* @param key - Storage key
|
|
34
|
+
* @returns Tokens if found, null otherwise
|
|
35
|
+
*/
|
|
36
|
+
retrieve(_key: string): Promise<DropboxOAuthTokens | null>;
|
|
37
|
+
/**
|
|
38
|
+
* Delete OAuth tokens
|
|
39
|
+
* @param key - Storage key
|
|
40
|
+
*/
|
|
41
|
+
delete(_key: string): Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Dropbox API token result structure
|
|
45
|
+
* This matches the structure returned by Dropbox SDK's getAccessTokenFromCode
|
|
46
|
+
*/
|
|
47
|
+
export interface DropboxTokenResult {
|
|
48
|
+
access_token: string;
|
|
49
|
+
refresh_token?: string;
|
|
50
|
+
expires_in?: number;
|
|
51
|
+
token_type?: string;
|
|
52
|
+
scope?: string;
|
|
53
|
+
account_id?: string;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,SAAS,CAAC,EAAE,IAAI,GAAG,SAAS,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,oBAAoB,EAAE,MAAM,CAAC;CAC9C;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEhE;;;;OAIG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAE3D;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
Copyright (c) 2025 Bernier LLC
|
|
4
|
+
|
|
5
|
+
This file is licensed to the client under a limited-use license.
|
|
6
|
+
The client may use and modify this code *only within the scope of the project it was delivered for*.
|
|
7
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA;;;;;;EAME"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bernierllc/dropbox-oauth",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "OAuth 2.0 authentication and token management for Dropbox",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"author": "Bernier LLC",
|
|
8
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"LICENSE"
|
|
12
|
+
],
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public",
|
|
15
|
+
"registry": "https://registry.npmjs.org/"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"dropbox": "^10.34.0",
|
|
19
|
+
"uuid": "^11.1.0",
|
|
20
|
+
"@bernierllc/logger": "1.0.3"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/jest": "^29.5.12",
|
|
24
|
+
"@types/node": "^20.12.12",
|
|
25
|
+
"@types/uuid": "^9.0.4",
|
|
26
|
+
"@typescript-eslint/eslint-plugin": "^7.9.0",
|
|
27
|
+
"@typescript-eslint/parser": "^7.9.0",
|
|
28
|
+
"eslint": "^8.57.0",
|
|
29
|
+
"eslint-config-prettier": "^9.1.0",
|
|
30
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
31
|
+
"jest": "^29.7.0",
|
|
32
|
+
"prettier": "^3.2.5",
|
|
33
|
+
"ts-jest": "^29.1.2",
|
|
34
|
+
"typescript": "^5.4.5"
|
|
35
|
+
},
|
|
36
|
+
"peerDependencies": {
|
|
37
|
+
"dropbox": "^10.34.0"
|
|
38
|
+
},
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsc",
|
|
41
|
+
"test": "jest",
|
|
42
|
+
"test:run": "jest --runInBand --collectCoverage",
|
|
43
|
+
"test:coverage": "jest --runInBand --collectCoverage",
|
|
44
|
+
"lint": "eslint \"src/**/*.ts\" \"__tests__/**/*.ts\" --max-warnings 0"
|
|
45
|
+
}
|
|
46
|
+
}
|