oauth-callback 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +231 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +13 -0
- package/index.ts +30 -0
- package/package.json +88 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025-present Konstantin Tarkus, Kriasoft
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# OAuth Callback Server
|
|
2
|
+
|
|
3
|
+
A lightweight local HTTP server for handling OAuth 2.0 authorization callbacks in Node.js/Bun applications. Perfect for CLI tools, desktop applications, and development environments that need to capture OAuth authorization codes.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 Simple async/await API
|
|
8
|
+
- 🔒 Secure local server for OAuth callbacks
|
|
9
|
+
- ⚡ Zero dependencies (when using Bun)
|
|
10
|
+
- 🎯 TypeScript support out of the box
|
|
11
|
+
- 🛡️ Built-in error handling for OAuth errors
|
|
12
|
+
- 🔄 Automatic server cleanup after callback
|
|
13
|
+
- 📱 Cross-platform support (Windows, macOS, Linux)
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
bun add oauth-callback
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or with npm:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install oauth-callback
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
import { getAuthCode, OAuthError } from "oauth-callback";
|
|
31
|
+
|
|
32
|
+
// Simple usage
|
|
33
|
+
const result = await getAuthCode(
|
|
34
|
+
"https://example.com/oauth/authorize?client_id=xxx&redirect_uri=http://localhost:3000/callback",
|
|
35
|
+
);
|
|
36
|
+
console.log("Authorization code:", result.code);
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Usage Examples
|
|
40
|
+
|
|
41
|
+
### Basic OAuth Flow
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { getAuthCode, OAuthError } from "oauth-callback";
|
|
45
|
+
|
|
46
|
+
async function authenticate() {
|
|
47
|
+
const authUrl =
|
|
48
|
+
"https://github.com/login/oauth/authorize?" +
|
|
49
|
+
new URLSearchParams({
|
|
50
|
+
client_id: "your_client_id",
|
|
51
|
+
redirect_uri: "http://localhost:3000/callback",
|
|
52
|
+
scope: "user:email",
|
|
53
|
+
state: "random_state_string",
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const result = await getAuthCode(authUrl);
|
|
58
|
+
console.log("Authorization code:", result.code);
|
|
59
|
+
console.log("State:", result.state);
|
|
60
|
+
|
|
61
|
+
// Exchange code for access token
|
|
62
|
+
// ... your token exchange logic here
|
|
63
|
+
} catch (error) {
|
|
64
|
+
if (error instanceof OAuthError) {
|
|
65
|
+
console.error("OAuth error:", error.error);
|
|
66
|
+
console.error("Description:", error.error_description);
|
|
67
|
+
} else {
|
|
68
|
+
console.error("Unexpected error:", error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Custom Port Configuration
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { getAuthCode } from "oauth-callback";
|
|
78
|
+
|
|
79
|
+
const result = await getAuthCode(authUrl, {
|
|
80
|
+
port: 8080, // Use custom port (default: 3000)
|
|
81
|
+
timeout: 60000, // Custom timeout in ms (default: 30000)
|
|
82
|
+
});
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Handling Different OAuth Providers
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
// Google OAuth
|
|
89
|
+
const googleAuth = await getAuthCode(
|
|
90
|
+
"https://accounts.google.com/o/oauth2/v2/auth?" +
|
|
91
|
+
new URLSearchParams({
|
|
92
|
+
client_id: process.env.GOOGLE_CLIENT_ID,
|
|
93
|
+
redirect_uri: "http://localhost:3000/callback",
|
|
94
|
+
response_type: "code",
|
|
95
|
+
scope: "openid email profile",
|
|
96
|
+
access_type: "offline",
|
|
97
|
+
}),
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
// Microsoft OAuth
|
|
101
|
+
const microsoftAuth = await getAuthCode(
|
|
102
|
+
"https://login.microsoftonline.com/common/oauth2/v2.0/authorize?" +
|
|
103
|
+
new URLSearchParams({
|
|
104
|
+
client_id: process.env.MICROSOFT_CLIENT_ID,
|
|
105
|
+
redirect_uri: "http://localhost:3000/callback",
|
|
106
|
+
response_type: "code",
|
|
107
|
+
scope: "user.read",
|
|
108
|
+
response_mode: "query",
|
|
109
|
+
}),
|
|
110
|
+
);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## API Reference
|
|
114
|
+
|
|
115
|
+
### `getAuthCode(authUrl, options?)`
|
|
116
|
+
|
|
117
|
+
Starts a local HTTP server and opens the authorization URL in the user's browser.
|
|
118
|
+
|
|
119
|
+
#### Parameters
|
|
120
|
+
|
|
121
|
+
- `authUrl` (string): The OAuth authorization URL
|
|
122
|
+
- `options` (object, optional):
|
|
123
|
+
- `port` (number): Port for the local server (default: 3000)
|
|
124
|
+
- `timeout` (number): Timeout in milliseconds (default: 30000)
|
|
125
|
+
- `callbackPath` (string): Callback path (default: "/callback")
|
|
126
|
+
- `successMessage` (string): Message shown on successful authorization
|
|
127
|
+
- `errorMessage` (string): Message shown on authorization error
|
|
128
|
+
|
|
129
|
+
#### Returns
|
|
130
|
+
|
|
131
|
+
Promise that resolves to:
|
|
132
|
+
|
|
133
|
+
```typescript
|
|
134
|
+
{
|
|
135
|
+
code: string; // Authorization code
|
|
136
|
+
state?: string; // State parameter (if provided)
|
|
137
|
+
[key: string]: any; // Additional query parameters
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
#### Throws
|
|
142
|
+
|
|
143
|
+
- `OAuthError`: When the OAuth provider returns an error
|
|
144
|
+
- `TimeoutError`: When the authorization times out
|
|
145
|
+
- `Error`: For other unexpected errors
|
|
146
|
+
|
|
147
|
+
### `OAuthError`
|
|
148
|
+
|
|
149
|
+
Custom error class for OAuth-specific errors.
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
class OAuthError extends Error {
|
|
153
|
+
error: string; // OAuth error code
|
|
154
|
+
error_description?: string; // Human-readable error description
|
|
155
|
+
error_uri?: string; // URI with error information
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## How It Works
|
|
160
|
+
|
|
161
|
+
1. **Server Creation**: Creates a temporary HTTP server on the specified port
|
|
162
|
+
2. **Browser Launch**: Opens the authorization URL in the user's default browser
|
|
163
|
+
3. **Callback Handling**: Waits for the OAuth provider to redirect back with the authorization code
|
|
164
|
+
4. **Cleanup**: Automatically closes the server after receiving the callback
|
|
165
|
+
5. **Result**: Returns the authorization code and any additional parameters
|
|
166
|
+
|
|
167
|
+
## Security Considerations
|
|
168
|
+
|
|
169
|
+
- The server only accepts connections from localhost
|
|
170
|
+
- Automatically validates the state parameter if provided
|
|
171
|
+
- Server is closed immediately after receiving the callback
|
|
172
|
+
- Supports PKCE (Proof Key for Code Exchange) flow
|
|
173
|
+
- No data is stored persistently
|
|
174
|
+
|
|
175
|
+
## Development
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
# Install dependencies
|
|
179
|
+
bun install
|
|
180
|
+
|
|
181
|
+
# Run tests
|
|
182
|
+
bun test
|
|
183
|
+
|
|
184
|
+
# Build
|
|
185
|
+
bun build ./src/index.ts --outdir ./dist
|
|
186
|
+
|
|
187
|
+
# Run example
|
|
188
|
+
bun run example.ts
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## Requirements
|
|
192
|
+
|
|
193
|
+
- Node.js 14+ or Bun 1.0+
|
|
194
|
+
- A registered OAuth application with a provider
|
|
195
|
+
- Redirect URI configured as `http://localhost:[port]/callback`
|
|
196
|
+
|
|
197
|
+
## Common Issues
|
|
198
|
+
|
|
199
|
+
### Port Already in Use
|
|
200
|
+
|
|
201
|
+
If port 3000 is already in use, specify a different port:
|
|
202
|
+
|
|
203
|
+
```typescript
|
|
204
|
+
const result = await getAuthCode(authUrl, { port: 8080 });
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
### Firewall Warnings
|
|
208
|
+
|
|
209
|
+
On first run, your OS may show a firewall warning. Allow the connection for localhost only.
|
|
210
|
+
|
|
211
|
+
### Browser Doesn't Open
|
|
212
|
+
|
|
213
|
+
If the browser doesn't open automatically, manually navigate to the authorization URL.
|
|
214
|
+
|
|
215
|
+
## Contributing
|
|
216
|
+
|
|
217
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
218
|
+
|
|
219
|
+
1. Fork the repository
|
|
220
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
221
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
222
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
223
|
+
5. Open a Pull Request
|
|
224
|
+
|
|
225
|
+
## License
|
|
226
|
+
|
|
227
|
+
This project is released under the MIT License. Feel free to use it in your projects, modify it to suit your needs, and share it with others. We believe in open source and hope this tool makes OAuth integration easier for everyone!
|
|
228
|
+
|
|
229
|
+
## Support
|
|
230
|
+
|
|
231
|
+
Found a bug or have a question? Please open an issue on the [GitHub issue tracker](https://github.com/koistya/oauth-callback/issues) and we'll be happy to help. If this project saves you time and you'd like to support its continued development, consider [becoming a sponsor](https://github.com/sponsors/koistya). Every bit of support helps maintain and improve this tool for the community. Thank you!
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the OAuth authorization code from the authorization URL.
|
|
3
|
+
*
|
|
4
|
+
* @param input Authorization URL or authorization options.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getAuthCode(input: {
|
|
7
|
+
/** OAuth authorization URL */
|
|
8
|
+
authorizeUrl: string;
|
|
9
|
+
/** @default 3000 */
|
|
10
|
+
port?: number;
|
|
11
|
+
/** @default true */
|
|
12
|
+
throwOnError?: boolean;
|
|
13
|
+
/** @default true */
|
|
14
|
+
openBrowser?: boolean;
|
|
15
|
+
} | string): Promise<void>;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// index.ts
|
|
2
|
+
async function getAuthCode(input) {
|
|
3
|
+
const {
|
|
4
|
+
authorizeUrl,
|
|
5
|
+
port = 3000,
|
|
6
|
+
throwOnError = true,
|
|
7
|
+
openBrowser = true
|
|
8
|
+
} = typeof input === "string" ? { authorizeUrl: input } : input;
|
|
9
|
+
throw new Error("Not implemented");
|
|
10
|
+
}
|
|
11
|
+
export {
|
|
12
|
+
getAuthCode
|
|
13
|
+
};
|
package/index.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { createServer } from "node:http";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get the OAuth authorization code from the authorization URL.
|
|
5
|
+
*
|
|
6
|
+
* @param input Authorization URL or authorization options.
|
|
7
|
+
*/
|
|
8
|
+
export async function getAuthCode(
|
|
9
|
+
input:
|
|
10
|
+
| {
|
|
11
|
+
/** OAuth authorization URL */
|
|
12
|
+
authorizeUrl: string;
|
|
13
|
+
/** @default 3000 */
|
|
14
|
+
port?: number;
|
|
15
|
+
/** @default true */
|
|
16
|
+
throwOnError?: boolean;
|
|
17
|
+
/** @default true */
|
|
18
|
+
openBrowser?: boolean;
|
|
19
|
+
}
|
|
20
|
+
| string,
|
|
21
|
+
) {
|
|
22
|
+
const {
|
|
23
|
+
authorizeUrl,
|
|
24
|
+
port = 3000,
|
|
25
|
+
throwOnError = true,
|
|
26
|
+
openBrowser = true,
|
|
27
|
+
} = typeof input === "string" ? { authorizeUrl: input } : input;
|
|
28
|
+
|
|
29
|
+
throw new Error("Not implemented");
|
|
30
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "oauth-callback",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Lightweight OAuth 2.0 and OpenID Connect callback handler for Node.js, Deno and Bun applications with RFC 6749 and RFC 7591 compliance",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"oauth",
|
|
7
|
+
"callback",
|
|
8
|
+
"authentication",
|
|
9
|
+
"auth",
|
|
10
|
+
"bun",
|
|
11
|
+
"oauth2",
|
|
12
|
+
"login",
|
|
13
|
+
"authorization",
|
|
14
|
+
"web",
|
|
15
|
+
"handler",
|
|
16
|
+
"security",
|
|
17
|
+
"redirect",
|
|
18
|
+
"token",
|
|
19
|
+
"javascript",
|
|
20
|
+
"typescript",
|
|
21
|
+
"rfc6749",
|
|
22
|
+
"rfc7591",
|
|
23
|
+
"openid",
|
|
24
|
+
"oidc",
|
|
25
|
+
"client",
|
|
26
|
+
"server",
|
|
27
|
+
"middleware",
|
|
28
|
+
"express",
|
|
29
|
+
"fastify",
|
|
30
|
+
"session",
|
|
31
|
+
"jwt",
|
|
32
|
+
"bearer",
|
|
33
|
+
"access-token",
|
|
34
|
+
"refresh-token"
|
|
35
|
+
],
|
|
36
|
+
"author": "Konstantin Tarkus <koistya@kriasoft.com>",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "https://github.com/kriasoft/oauth-callback.git"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/kriasoft/oauth-callback",
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/kriasoft/oauth-callback/issues"
|
|
45
|
+
},
|
|
46
|
+
"funding": {
|
|
47
|
+
"type": "github",
|
|
48
|
+
"url": "https://github.com/sponsors/koistya"
|
|
49
|
+
},
|
|
50
|
+
"files": [
|
|
51
|
+
"dist",
|
|
52
|
+
"index.ts",
|
|
53
|
+
"LICENSE",
|
|
54
|
+
"README.md"
|
|
55
|
+
],
|
|
56
|
+
"module": "dist/index.js",
|
|
57
|
+
"types": "dist/index.d.ts",
|
|
58
|
+
"type": "module",
|
|
59
|
+
"exports": {
|
|
60
|
+
".": {
|
|
61
|
+
"bun": "./index.ts",
|
|
62
|
+
"deno": "./index.ts",
|
|
63
|
+
"types": "./dist/index.d.ts",
|
|
64
|
+
"default": "./dist/index.js"
|
|
65
|
+
},
|
|
66
|
+
"./package.json": "./package.json"
|
|
67
|
+
},
|
|
68
|
+
"peerDependencies": {
|
|
69
|
+
"typescript": "^5"
|
|
70
|
+
},
|
|
71
|
+
"devDependencies": {
|
|
72
|
+
"@types/bun": "latest",
|
|
73
|
+
"typescript": "^5.9.2",
|
|
74
|
+
"prettier": "^3.6.2"
|
|
75
|
+
},
|
|
76
|
+
"prettier": {
|
|
77
|
+
"printWidth": 80,
|
|
78
|
+
"tabWidth": 2,
|
|
79
|
+
"useTabs": false,
|
|
80
|
+
"singleQuote": false,
|
|
81
|
+
"trailingComma": "all"
|
|
82
|
+
},
|
|
83
|
+
"scripts": {
|
|
84
|
+
"build": "bun build ./index.ts --outdir=./dist --target=node && tsc --declaration --emitDeclarationOnly --outDir ./dist",
|
|
85
|
+
"prepublishOnly": "bun run build",
|
|
86
|
+
"test": "bun test"
|
|
87
|
+
}
|
|
88
|
+
}
|