oauth-callback 1.2.0 → 1.2.2

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/dist/server.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * SPDX-License-Identifier: MIT
6
6
  */
7
7
  /**
8
- * Result object returned from OAuth callback containing authorization code or error details
8
+ * Result object returned from OAuth callback containing authorization code or error details.
9
9
  */
10
10
  export interface CallbackResult {
11
11
  /** Authorization code returned by OAuth provider */
@@ -22,7 +22,7 @@ export interface CallbackResult {
22
22
  [key: string]: string | undefined;
23
23
  }
24
24
  /**
25
- * Configuration options for the OAuth callback server
25
+ * Configuration options for the OAuth callback server.
26
26
  */
27
27
  export interface ServerOptions {
28
28
  /** Port number to bind the server to */
@@ -39,7 +39,7 @@ export interface ServerOptions {
39
39
  onRequest?: (req: Request) => void;
40
40
  }
41
41
  /**
42
- * Interface for OAuth callback server implementations across different runtimes
42
+ * Interface for OAuth callback server implementations across different runtimes.
43
43
  */
44
44
  export interface CallbackServer {
45
45
  /** Start the HTTP server with the given options */
@@ -50,9 +50,9 @@ export interface CallbackServer {
50
50
  stop(): Promise<void>;
51
51
  }
52
52
  /**
53
- * Create a callback server for the current runtime (Bun, Deno, or Node.js)
54
- * Automatically detects the runtime and returns appropriate server implementation
55
- * @returns CallbackServer instance optimized for the current runtime
53
+ * Create a callback server for the current runtime (Bun, Deno, or Node.js).
54
+ * Automatically detects the runtime and returns the appropriate server implementation.
55
+ * @returns CallbackServer instance optimized for the current runtime.
56
56
  */
57
57
  export declare function createCallbackServer(): CallbackServer;
58
58
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mHAAmH;IACnH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oFAAoF;IACpF,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,KAAK,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,iEAAiE;IACjE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACxE,4CAA4C;IAC5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAuhBD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAarD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uCAAuC;IACvC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,4CAA4C;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mHAAmH;IACnH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,oFAAoF;IACpF,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,mDAAmD;IACnD,KAAK,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,iEAAiE;IACjE,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACxE,4CAA4C;IAC5C,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB;AAyRD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,cAAc,CAKrD"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oauth-callback",
3
- "version": "1.2.0",
4
- "description": "Lightweight OAuth 2.0 callback handler for Node.js, Deno, and Bun with built-in browser flow, MCP support, and zero dependencies",
3
+ "version": "1.2.2",
4
+ "description": "Lightweight OAuth 2.0 callback handler for Node.js, Deno, and Bun with built-in browser flow and MCP SDK integration",
5
5
  "keywords": [
6
6
  "oauth",
7
7
  "oauth2",
@@ -35,7 +35,7 @@
35
35
  "type": "git",
36
36
  "url": "git+https://github.com/kriasoft/oauth-callback.git"
37
37
  },
38
- "homepage": "https://github.com/kriasoft/oauth-callback",
38
+ "homepage": "https://kriasoft.com/oauth-callback",
39
39
  "bugs": {
40
40
  "url": "https://github.com/kriasoft/oauth-callback/issues"
41
41
  },
@@ -64,7 +64,7 @@
64
64
  "./package.json": "./package.json"
65
65
  },
66
66
  "dependencies": {
67
- "open": "^10.2.0"
67
+ "open": "^11.0.0"
68
68
  },
69
69
  "peerDependencies": {
70
70
  "@modelcontextprotocol/sdk": ">=1.17.0 <2",
@@ -79,11 +79,18 @@
79
79
  }
80
80
  },
81
81
  "devDependencies": {
82
- "@modelcontextprotocol/sdk": "^1.17.3",
83
- "@types/bun": "^1.2.20",
84
- "prettier": "^3.6.2",
85
- "publint": "^0.3.12",
86
- "typescript": "^5.9.2"
82
+ "@modelcontextprotocol/sdk": "^1.25.2",
83
+ "@types/bun": "^1.3.6",
84
+ "@types/deno": "^2.5.0",
85
+ "@types/node": "^24.10.9",
86
+ "@types/open": "^6.2.1",
87
+ "bun-types": "^1.2.20",
88
+ "mermaid": "^11.12.2",
89
+ "prettier": "^3.8.0",
90
+ "publint": "^0.3.16",
91
+ "typescript": "^5.9.3",
92
+ "vitepress": "^1.6.4",
93
+ "vitepress-plugin-mermaid": "^2.0.17"
87
94
  },
88
95
  "prettier": {
89
96
  "trailingComma": "all",
@@ -106,6 +113,10 @@
106
113
  "example:github": "bun run examples/github.ts",
107
114
  "example:notion": "bun run examples/notion.ts",
108
115
  "example:mcp-auth": "bun run examples/mcp-auth.ts",
109
- "prepublishOnly": "bun run build && bun run lint:package"
116
+ "prepublishOnly": "bun run build && bun run lint:package",
117
+ "docs:dev": "vitepress dev docs",
118
+ "docs:build": "vitepress build docs",
119
+ "docs:preview": "vitepress preview docs",
120
+ "docs:publish": "bunx gh-pages -d docs/.vitepress/dist"
110
121
  }
111
122
  }
@@ -0,0 +1,204 @@
1
+ import { expect, test, describe } from "bun:test";
2
+ import { OAuthError, TimeoutError } from "./errors";
3
+
4
+ describe("OAuthError", () => {
5
+ describe("constructor", () => {
6
+ test("sets all properties correctly", () => {
7
+ const e = new OAuthError(
8
+ "access_denied",
9
+ "User denied access",
10
+ "https://ex.com/e",
11
+ );
12
+ expect(e).toBeInstanceOf(OAuthError);
13
+ expect(e).toBeInstanceOf(Error);
14
+ expect(e.name).toBe("OAuthError");
15
+ expect(e.error).toBe("access_denied");
16
+ expect(e.error_description).toBe("User denied access");
17
+ expect(e.error_uri).toBe("https://ex.com/e");
18
+ expect(typeof e.stack).toBe("string");
19
+ expect(e.stack!.startsWith("OAuthError")).toBeTrue();
20
+ });
21
+
22
+ test("uses error code as message when description is not provided", () => {
23
+ const error = new OAuthError("server_error");
24
+ expect(error.message).toBe("server_error");
25
+ expect(error.error_description).toBeUndefined();
26
+ });
27
+
28
+ test("sets optional parameters correctly", () => {
29
+ const error1 = new OAuthError("invalid_request", "Bad request");
30
+ expect(error1.error_description).toBe("Bad request");
31
+ expect(error1.error_uri).toBeUndefined();
32
+
33
+ const error2 = new OAuthError("invalid_request");
34
+ expect(error2.error_description).toBeUndefined();
35
+ expect(error2.error_uri).toBeUndefined();
36
+ });
37
+ });
38
+
39
+ describe("inheritance", () => {
40
+ test("extends native Error class", () => {
41
+ const error = new OAuthError("invalid_request");
42
+ expect(error instanceof Error).toBe(true);
43
+ expect(error instanceof OAuthError).toBe(true);
44
+ });
45
+
46
+ test("has correct name property", () => {
47
+ const error = new OAuthError("any_error");
48
+ expect(error.name).toBe("OAuthError");
49
+ });
50
+
51
+ test("maintains proper stack trace", () => {
52
+ const error = new OAuthError("unauthorized_client");
53
+ expect(typeof error.stack).toBe("string");
54
+ expect(error.stack!.includes("OAuthError")).toBe(true);
55
+ expect(error.stack!.includes(error.message)).toBe(true);
56
+ });
57
+ });
58
+
59
+ describe("edge cases", () => {
60
+ test("handles empty string parameters", () => {
61
+ const error = new OAuthError("", "", "");
62
+ expect(error.error).toBe("");
63
+ expect(error.message).toBe("");
64
+ expect(error.error_description).toBe("");
65
+ expect(error.error_uri).toBe("");
66
+ });
67
+
68
+ test("handles very long strings", () => {
69
+ const longString = "x".repeat(10000);
70
+ const error = new OAuthError(longString, longString, longString);
71
+ expect(error.error).toBe(longString);
72
+ expect(error.error_description).toBe(longString);
73
+ expect(error.error_uri).toBe(longString);
74
+ expect(error.message).toBe(longString);
75
+ });
76
+
77
+ test("handles special characters and unicode", () => {
78
+ const special = "错误 🚨 <script>alert('xss')</script>";
79
+ const error = new OAuthError(special, special, special);
80
+ expect(error.error).toBe(special);
81
+ expect(error.error_description).toBe(special);
82
+ expect(error.error_uri).toBe(special);
83
+ });
84
+ });
85
+
86
+ describe("serialization", () => {
87
+ test("JSON.stringify includes custom properties and name", () => {
88
+ const error = new OAuthError(
89
+ "access_denied",
90
+ "User denied access",
91
+ "https://example.com/error",
92
+ );
93
+ const json = JSON.stringify(error);
94
+ const parsed = JSON.parse(json);
95
+
96
+ expect(parsed.error).toBe("access_denied");
97
+ expect(parsed.error_description).toBe("User denied access");
98
+ expect(parsed.error_uri).toBe("https://example.com/error");
99
+ expect(parsed.name).toBe("OAuthError");
100
+ expect(parsed.message).toBeUndefined();
101
+ expect(parsed.stack).toBeUndefined();
102
+ });
103
+
104
+ test("JSON.stringify with minimal properties", () => {
105
+ const error = new OAuthError("invalid_grant");
106
+ const json = JSON.stringify(error);
107
+ const parsed = JSON.parse(json);
108
+
109
+ expect(parsed.error).toBe("invalid_grant");
110
+ expect(parsed.error_description).toBeUndefined();
111
+ expect(parsed.error_uri).toBeUndefined();
112
+ expect(parsed.name).toBe("OAuthError");
113
+ });
114
+ });
115
+
116
+ describe("comparison", () => {
117
+ test("two errors with same properties are not equal by reference", () => {
118
+ const e1 = new OAuthError("same", "desc", "uri");
119
+ const e2 = new OAuthError("same", "desc", "uri");
120
+ expect(e1 === e2).toBe(false);
121
+ expect(e1).not.toBe(e2);
122
+ });
123
+
124
+ test("errors have different stack traces even with same properties", () => {
125
+ const e1 = new OAuthError("same");
126
+ const e2 = new OAuthError("same");
127
+ expect(e1.stack).not.toBe(e2.stack);
128
+ });
129
+ });
130
+ });
131
+
132
+ describe("TimeoutError", () => {
133
+ describe("constructor", () => {
134
+ test("has correct name property", () => {
135
+ const error = new TimeoutError();
136
+ expect(error.name).toBe("TimeoutError");
137
+ });
138
+
139
+ test("uses default message when not provided", () => {
140
+ const error = new TimeoutError();
141
+ expect(error.message).toBe("OAuth callback timed out");
142
+ });
143
+
144
+ test("uses custom message when provided", () => {
145
+ const error = new TimeoutError("It took too long, please try again.");
146
+ expect(error.message).toBe("It took too long, please try again.");
147
+ });
148
+ });
149
+
150
+ describe("inheritance", () => {
151
+ test("extends native Error class", () => {
152
+ const error = new TimeoutError();
153
+ expect(error instanceof Error).toBe(true);
154
+ expect(error instanceof TimeoutError).toBe(true);
155
+ });
156
+
157
+ test("maintains proper stack trace", () => {
158
+ const error = new TimeoutError("Custom timeout message");
159
+ expect(typeof error.stack).toBe("string");
160
+ expect(error.stack!.includes("TimeoutError")).toBe(true);
161
+ expect(error.stack!.includes(error.message)).toBe(true);
162
+ });
163
+ });
164
+
165
+ describe("edge cases", () => {
166
+ test("handles empty string message", () => {
167
+ const error = new TimeoutError("");
168
+ expect(error.message).toBe("");
169
+ });
170
+
171
+ test("handles very long message", () => {
172
+ const longMessage = "Timeout: " + "x".repeat(10000);
173
+ const error = new TimeoutError(longMessage);
174
+ expect(error.message).toBe(longMessage);
175
+ });
176
+ });
177
+
178
+ describe("serialization", () => {
179
+ test("JSON.stringify only includes name property", () => {
180
+ const error = new TimeoutError("Custom message");
181
+ const json = JSON.stringify(error);
182
+ const parsed = JSON.parse(json);
183
+
184
+ expect(parsed).toEqual({ name: "TimeoutError" });
185
+ expect(parsed.message).toBeUndefined();
186
+ expect(parsed.stack).toBeUndefined();
187
+ });
188
+ });
189
+
190
+ describe("comparison", () => {
191
+ test("two errors with same message are not equal by reference", () => {
192
+ const e1 = new TimeoutError("Same message");
193
+ const e2 = new TimeoutError("Same message");
194
+ expect(e1 === e2).toBe(false);
195
+ expect(e1).not.toBe(e2);
196
+ });
197
+
198
+ test("errors have different stack traces even with same message", () => {
199
+ const e1 = new TimeoutError();
200
+ const e2 = new TimeoutError();
201
+ expect(e1.stack).not.toBe(e2.stack);
202
+ });
203
+ });
204
+ });