@uln/auth 0.4.0 → 0.4.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/client.d.ts +1 -0
- package/dist/client.js +10 -25
- package/dist/hono.d.ts +1 -3
- package/dist/hono.js +1 -18
- package/dist/index.js +10 -25
- package/dist/middleware.d.ts +3 -3
- package/dist/middleware.js +10 -25
- package/dist/service.d.ts +2 -3
- package/dist/service.js +10 -24
- package/package.json +2 -2
- package/src/client.ts +1 -0
- package/src/hono.ts +4 -27
- package/src/middleware.ts +7 -22
- package/src/service.ts +6 -20
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type { TokenPayload, VerifyConfig, PublicKeyEntry, CookieConfig } from "./types.ts";
|
|
2
2
|
export { validateToken, importPublicKey } from "./token.ts";
|
|
3
3
|
export { makeSessionCookie, makeClearCookie, extractCookie } from "./cookie.ts";
|
|
4
|
+
export type { AuthCodeExchangeConfig } from "./middleware.ts";
|
|
4
5
|
export { getAuthUser, redirectToLogin, handleCallback, getClientIP, checkBearerToken } from "./middleware.ts";
|
|
5
6
|
import type { PublicKeyEntry } from "./types.ts";
|
|
6
7
|
export declare function fetchPublicKeys(baseUrl: string): Promise<PublicKeyEntry[]>;
|
package/dist/client.js
CHANGED
|
@@ -130,11 +130,10 @@ async function getAuthUser(request, verifyConfig, cookieConfig) {
|
|
|
130
130
|
return null;
|
|
131
131
|
return validateToken(verifyConfig, token);
|
|
132
132
|
}
|
|
133
|
-
function redirectToLogin(currentUrl
|
|
133
|
+
function redirectToLogin(currentUrl) {
|
|
134
134
|
const loginUrl = new URL("/login", "https://auth.uln.industries");
|
|
135
135
|
loginUrl.searchParams.set("redirect", currentUrl);
|
|
136
|
-
|
|
137
|
-
loginUrl.searchParams.set("response_type", "code");
|
|
136
|
+
loginUrl.searchParams.set("response_type", "code");
|
|
138
137
|
return Response.redirect(loginUrl.toString(), 302);
|
|
139
138
|
}
|
|
140
139
|
async function exchangeCode(code, redirectOrigin, config) {
|
|
@@ -154,36 +153,22 @@ async function handleCallback(request, verifyConfig, cookieConfig, exchangeConfi
|
|
|
154
153
|
if (code) {
|
|
155
154
|
if (!exchangeConfig)
|
|
156
155
|
return redirectToLogin(url.origin);
|
|
157
|
-
const
|
|
158
|
-
if (!
|
|
159
|
-
return redirectToLogin(url.origin
|
|
160
|
-
const
|
|
161
|
-
if (!
|
|
162
|
-
return redirectToLogin(url.origin
|
|
156
|
+
const token = await exchangeCode(code, url.origin, exchangeConfig);
|
|
157
|
+
if (!token)
|
|
158
|
+
return redirectToLogin(url.origin);
|
|
159
|
+
const payload = await validateToken(verifyConfig, token);
|
|
160
|
+
if (!payload)
|
|
161
|
+
return redirectToLogin(url.origin);
|
|
163
162
|
url.searchParams.delete("code");
|
|
164
163
|
return new Response(null, {
|
|
165
164
|
status: 302,
|
|
166
165
|
headers: {
|
|
167
166
|
Location: url.toString(),
|
|
168
|
-
"Set-Cookie": makeSessionCookie(cookieConfig,
|
|
167
|
+
"Set-Cookie": makeSessionCookie(cookieConfig, token)
|
|
169
168
|
}
|
|
170
169
|
});
|
|
171
170
|
}
|
|
172
|
-
|
|
173
|
-
if (!token)
|
|
174
|
-
return null;
|
|
175
|
-
const payload = await validateToken(verifyConfig, token);
|
|
176
|
-
if (!payload) {
|
|
177
|
-
return redirectToLogin(url.origin);
|
|
178
|
-
}
|
|
179
|
-
url.searchParams.delete("token");
|
|
180
|
-
return new Response(null, {
|
|
181
|
-
status: 302,
|
|
182
|
-
headers: {
|
|
183
|
-
Location: url.toString(),
|
|
184
|
-
"Set-Cookie": makeSessionCookie(cookieConfig, token)
|
|
185
|
-
}
|
|
186
|
-
});
|
|
171
|
+
return null;
|
|
187
172
|
}
|
|
188
173
|
// src/client.ts
|
|
189
174
|
async function fetchPublicKeys(baseUrl) {
|
package/dist/hono.d.ts
CHANGED
|
@@ -19,13 +19,11 @@ interface AuthOptions {
|
|
|
19
19
|
cookie?: string;
|
|
20
20
|
/** Cookie/token max age in seconds. Defaults to 86400 (24h). */
|
|
21
21
|
maxAge?: number;
|
|
22
|
-
/** Redirect callback mode. "code" avoids putting signed tokens in URLs. Defaults to "code". */
|
|
23
|
-
responseType?: "code" | "token";
|
|
24
22
|
}
|
|
25
23
|
/**
|
|
26
24
|
* Hono middleware that handles the full auth flow:
|
|
27
25
|
*
|
|
28
|
-
* 1. If `?
|
|
26
|
+
* 1. If `?code=` in URL → exchange for token, set cookie, redirect to clean URL
|
|
29
27
|
* 2. If session cookie present → validate, set `c.get("user")`
|
|
30
28
|
* 3. If unauthenticated → redirect to auth.uln.industries/login
|
|
31
29
|
*
|
package/dist/hono.js
CHANGED
|
@@ -198,7 +198,6 @@ function auth(options) {
|
|
|
198
198
|
const authUrl = options?.authUrl ?? DEFAULT_AUTH_URL;
|
|
199
199
|
const cookieName = options?.cookie ?? DEFAULT_COOKIE;
|
|
200
200
|
const maxAge = options?.maxAge ?? DEFAULT_MAX_AGE;
|
|
201
|
-
const responseType = options?.responseType ?? "code";
|
|
202
201
|
const publicPaths = options?.public ?? [];
|
|
203
202
|
const bindingName = options?.binding;
|
|
204
203
|
const cookieConf = { name: cookieName, maxAgeSeconds: maxAge, secure: true };
|
|
@@ -244,21 +243,6 @@ function auth(options) {
|
|
|
244
243
|
}
|
|
245
244
|
});
|
|
246
245
|
}
|
|
247
|
-
const incomingToken = url.searchParams.get("token");
|
|
248
|
-
if (incomingToken) {
|
|
249
|
-
const payload = await validate(incomingToken, c.env);
|
|
250
|
-
if (!payload) {
|
|
251
|
-
return c.text("Invalid token", 401);
|
|
252
|
-
}
|
|
253
|
-
url.searchParams.delete("token");
|
|
254
|
-
return new Response(null, {
|
|
255
|
-
status: 302,
|
|
256
|
-
headers: {
|
|
257
|
-
Location: url.toString(),
|
|
258
|
-
"Set-Cookie": makeSessionCookie(cookieConf, incomingToken)
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
246
|
const cookieHeader = c.req.header("Cookie");
|
|
263
247
|
if (cookieHeader) {
|
|
264
248
|
const token = extractCookie(cookieHeader, cookieName);
|
|
@@ -282,8 +266,7 @@ function auth(options) {
|
|
|
282
266
|
}
|
|
283
267
|
const loginUrl = new URL("/login", authUrl);
|
|
284
268
|
loginUrl.searchParams.set("redirect", c.req.url);
|
|
285
|
-
|
|
286
|
-
loginUrl.searchParams.set("response_type", "code");
|
|
269
|
+
loginUrl.searchParams.set("response_type", "code");
|
|
287
270
|
return c.redirect(loginUrl.toString(), 302);
|
|
288
271
|
};
|
|
289
272
|
}
|
package/dist/index.js
CHANGED
|
@@ -130,11 +130,10 @@ async function getAuthUser(request, verifyConfig, cookieConfig) {
|
|
|
130
130
|
return null;
|
|
131
131
|
return validateToken(verifyConfig, token);
|
|
132
132
|
}
|
|
133
|
-
function redirectToLogin(currentUrl
|
|
133
|
+
function redirectToLogin(currentUrl) {
|
|
134
134
|
const loginUrl = new URL("/login", "https://auth.uln.industries");
|
|
135
135
|
loginUrl.searchParams.set("redirect", currentUrl);
|
|
136
|
-
|
|
137
|
-
loginUrl.searchParams.set("response_type", "code");
|
|
136
|
+
loginUrl.searchParams.set("response_type", "code");
|
|
138
137
|
return Response.redirect(loginUrl.toString(), 302);
|
|
139
138
|
}
|
|
140
139
|
async function exchangeCode(code, redirectOrigin, config) {
|
|
@@ -154,36 +153,22 @@ async function handleCallback(request, verifyConfig, cookieConfig, exchangeConfi
|
|
|
154
153
|
if (code) {
|
|
155
154
|
if (!exchangeConfig)
|
|
156
155
|
return redirectToLogin(url.origin);
|
|
157
|
-
const
|
|
158
|
-
if (!
|
|
159
|
-
return redirectToLogin(url.origin
|
|
160
|
-
const
|
|
161
|
-
if (!
|
|
162
|
-
return redirectToLogin(url.origin
|
|
156
|
+
const token = await exchangeCode(code, url.origin, exchangeConfig);
|
|
157
|
+
if (!token)
|
|
158
|
+
return redirectToLogin(url.origin);
|
|
159
|
+
const payload = await validateToken(verifyConfig, token);
|
|
160
|
+
if (!payload)
|
|
161
|
+
return redirectToLogin(url.origin);
|
|
163
162
|
url.searchParams.delete("code");
|
|
164
163
|
return new Response(null, {
|
|
165
164
|
status: 302,
|
|
166
165
|
headers: {
|
|
167
166
|
Location: url.toString(),
|
|
168
|
-
"Set-Cookie": makeSessionCookie(cookieConfig,
|
|
167
|
+
"Set-Cookie": makeSessionCookie(cookieConfig, token)
|
|
169
168
|
}
|
|
170
169
|
});
|
|
171
170
|
}
|
|
172
|
-
|
|
173
|
-
if (!token)
|
|
174
|
-
return null;
|
|
175
|
-
const payload = await validateToken(verifyConfig, token);
|
|
176
|
-
if (!payload) {
|
|
177
|
-
return redirectToLogin(url.origin);
|
|
178
|
-
}
|
|
179
|
-
url.searchParams.delete("token");
|
|
180
|
-
return new Response(null, {
|
|
181
|
-
status: 302,
|
|
182
|
-
headers: {
|
|
183
|
-
Location: url.toString(),
|
|
184
|
-
"Set-Cookie": makeSessionCookie(cookieConfig, token)
|
|
185
|
-
}
|
|
186
|
-
});
|
|
171
|
+
return null;
|
|
187
172
|
}
|
|
188
173
|
|
|
189
174
|
// src/password.ts
|
package/dist/middleware.d.ts
CHANGED
|
@@ -5,11 +5,11 @@ export interface AuthCodeExchangeConfig {
|
|
|
5
5
|
export declare function getClientIP(request: Request): string;
|
|
6
6
|
export declare function checkBearerToken(request: Request, expectedToken: string): boolean;
|
|
7
7
|
export declare function getAuthUser(request: Request, verifyConfig: VerifyConfig, cookieConfig: CookieConfig): Promise<TokenPayload | null>;
|
|
8
|
-
export declare function redirectToLogin(currentUrl: string
|
|
8
|
+
export declare function redirectToLogin(currentUrl: string): Response;
|
|
9
9
|
/**
|
|
10
10
|
* Handle the auth callback on consuming sites.
|
|
11
|
-
* If the request URL has a `?code=`
|
|
12
|
-
* and redirects to the same URL without the
|
|
11
|
+
* If the request URL has a `?code=` param, exchanges it for a token,
|
|
12
|
+
* sets a session cookie, and redirects to the same URL without the code param.
|
|
13
13
|
* Returns null if there's no callback param.
|
|
14
14
|
*/
|
|
15
15
|
export declare function handleCallback(request: Request, verifyConfig: VerifyConfig, cookieConfig: CookieConfig, exchangeConfig?: AuthCodeExchangeConfig): Promise<Response | null>;
|
package/dist/middleware.js
CHANGED
|
@@ -130,11 +130,10 @@ async function getAuthUser(request, verifyConfig, cookieConfig) {
|
|
|
130
130
|
return null;
|
|
131
131
|
return validateToken(verifyConfig, token);
|
|
132
132
|
}
|
|
133
|
-
function redirectToLogin(currentUrl
|
|
133
|
+
function redirectToLogin(currentUrl) {
|
|
134
134
|
const loginUrl = new URL("/login", "https://auth.uln.industries");
|
|
135
135
|
loginUrl.searchParams.set("redirect", currentUrl);
|
|
136
|
-
|
|
137
|
-
loginUrl.searchParams.set("response_type", "code");
|
|
136
|
+
loginUrl.searchParams.set("response_type", "code");
|
|
138
137
|
return Response.redirect(loginUrl.toString(), 302);
|
|
139
138
|
}
|
|
140
139
|
async function exchangeCode(code, redirectOrigin, config) {
|
|
@@ -154,36 +153,22 @@ async function handleCallback(request, verifyConfig, cookieConfig, exchangeConfi
|
|
|
154
153
|
if (code) {
|
|
155
154
|
if (!exchangeConfig)
|
|
156
155
|
return redirectToLogin(url.origin);
|
|
157
|
-
const
|
|
158
|
-
if (!
|
|
159
|
-
return redirectToLogin(url.origin
|
|
160
|
-
const
|
|
161
|
-
if (!
|
|
162
|
-
return redirectToLogin(url.origin
|
|
156
|
+
const token = await exchangeCode(code, url.origin, exchangeConfig);
|
|
157
|
+
if (!token)
|
|
158
|
+
return redirectToLogin(url.origin);
|
|
159
|
+
const payload = await validateToken(verifyConfig, token);
|
|
160
|
+
if (!payload)
|
|
161
|
+
return redirectToLogin(url.origin);
|
|
163
162
|
url.searchParams.delete("code");
|
|
164
163
|
return new Response(null, {
|
|
165
164
|
status: 302,
|
|
166
165
|
headers: {
|
|
167
166
|
Location: url.toString(),
|
|
168
|
-
"Set-Cookie": makeSessionCookie(cookieConfig,
|
|
167
|
+
"Set-Cookie": makeSessionCookie(cookieConfig, token)
|
|
169
168
|
}
|
|
170
169
|
});
|
|
171
170
|
}
|
|
172
|
-
|
|
173
|
-
if (!token)
|
|
174
|
-
return null;
|
|
175
|
-
const payload = await validateToken(verifyConfig, token);
|
|
176
|
-
if (!payload) {
|
|
177
|
-
return redirectToLogin(url.origin);
|
|
178
|
-
}
|
|
179
|
-
url.searchParams.delete("token");
|
|
180
|
-
return new Response(null, {
|
|
181
|
-
status: 302,
|
|
182
|
-
headers: {
|
|
183
|
-
Location: url.toString(),
|
|
184
|
-
"Set-Cookie": makeSessionCookie(cookieConfig, token)
|
|
185
|
-
}
|
|
186
|
-
});
|
|
171
|
+
return null;
|
|
187
172
|
}
|
|
188
173
|
export {
|
|
189
174
|
redirectToLogin,
|
package/dist/service.d.ts
CHANGED
|
@@ -13,13 +13,12 @@ export declare function verifyToken(authService: Fetcher, token: string): Promis
|
|
|
13
13
|
export declare function getAuthUser(request: Request, authService: Fetcher, cookieConfig: CookieConfig): Promise<TokenPayload | null>;
|
|
14
14
|
/**
|
|
15
15
|
* Redirect to the centralized login page at auth.uln.industries.
|
|
16
|
-
* Requests one-time auth-code callbacks
|
|
16
|
+
* Requests one-time auth-code callbacks so signed tokens are not sent through URLs.
|
|
17
17
|
*/
|
|
18
|
-
export declare function redirectToLogin(currentUrl: string
|
|
18
|
+
export declare function redirectToLogin(currentUrl: string): Response;
|
|
19
19
|
/**
|
|
20
20
|
* Handle an auth callback on a consuming Worker using the auth service binding.
|
|
21
21
|
* Preferred `?code=` callbacks are exchanged for signed tokens before setting the local cookie.
|
|
22
|
-
* Legacy `?token=` callbacks are still accepted during migration and are stripped immediately.
|
|
23
22
|
* Returns null if the request has no auth callback parameters.
|
|
24
23
|
*/
|
|
25
24
|
export declare function handleCallback(request: Request, authService: Fetcher, cookieConfig: CookieConfig): Promise<Response | null>;
|
package/dist/service.js
CHANGED
|
@@ -54,11 +54,10 @@ async function getAuthUser(request, authService, cookieConfig) {
|
|
|
54
54
|
return null;
|
|
55
55
|
return verifyToken(authService, token);
|
|
56
56
|
}
|
|
57
|
-
function redirectToLogin(currentUrl
|
|
57
|
+
function redirectToLogin(currentUrl) {
|
|
58
58
|
const loginUrl = new URL("/login", "https://auth.uln.industries");
|
|
59
59
|
loginUrl.searchParams.set("redirect", currentUrl);
|
|
60
|
-
|
|
61
|
-
loginUrl.searchParams.set("response_type", "code");
|
|
60
|
+
loginUrl.searchParams.set("response_type", "code");
|
|
62
61
|
return Response.redirect(loginUrl.toString(), 302);
|
|
63
62
|
}
|
|
64
63
|
async function exchangeCode(authService, code, redirectOrigin) {
|
|
@@ -76,35 +75,22 @@ async function handleCallback(request, authService, cookieConfig) {
|
|
|
76
75
|
const url = new URL(request.url);
|
|
77
76
|
const code = url.searchParams.get("code");
|
|
78
77
|
if (code) {
|
|
79
|
-
const
|
|
80
|
-
if (!
|
|
81
|
-
return redirectToLogin(url.origin
|
|
82
|
-
const
|
|
83
|
-
if (!
|
|
84
|
-
return redirectToLogin(url.origin
|
|
78
|
+
const token = await exchangeCode(authService, code, url.origin);
|
|
79
|
+
if (!token)
|
|
80
|
+
return redirectToLogin(url.origin);
|
|
81
|
+
const payload = await verifyToken(authService, token);
|
|
82
|
+
if (!payload)
|
|
83
|
+
return redirectToLogin(url.origin);
|
|
85
84
|
url.searchParams.delete("code");
|
|
86
85
|
return new Response(null, {
|
|
87
86
|
status: 302,
|
|
88
87
|
headers: {
|
|
89
88
|
Location: url.toString(),
|
|
90
|
-
"Set-Cookie": makeSessionCookie(cookieConfig,
|
|
89
|
+
"Set-Cookie": makeSessionCookie(cookieConfig, token)
|
|
91
90
|
}
|
|
92
91
|
});
|
|
93
92
|
}
|
|
94
|
-
|
|
95
|
-
if (!token)
|
|
96
|
-
return null;
|
|
97
|
-
const payload = await verifyToken(authService, token);
|
|
98
|
-
if (!payload)
|
|
99
|
-
return redirectToLogin(url.origin, "code");
|
|
100
|
-
url.searchParams.delete("token");
|
|
101
|
-
return new Response(null, {
|
|
102
|
-
status: 302,
|
|
103
|
-
headers: {
|
|
104
|
-
Location: url.toString(),
|
|
105
|
-
"Set-Cookie": makeSessionCookie(cookieConfig, token)
|
|
106
|
-
}
|
|
107
|
-
});
|
|
93
|
+
return null;
|
|
108
94
|
}
|
|
109
95
|
export {
|
|
110
96
|
verifyToken,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@uln/auth",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"hono": "^4",
|
|
60
|
-
"typescript": "^5"
|
|
60
|
+
"typescript": "^5 || ^6"
|
|
61
61
|
},
|
|
62
62
|
"peerDependenciesMeta": {
|
|
63
63
|
"hono": {
|
package/src/client.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export type { TokenPayload, VerifyConfig, PublicKeyEntry, CookieConfig } from "./types.ts";
|
|
2
2
|
export { validateToken, importPublicKey } from "./token.ts";
|
|
3
3
|
export { makeSessionCookie, makeClearCookie, extractCookie } from "./cookie.ts";
|
|
4
|
+
export type { AuthCodeExchangeConfig } from "./middleware.ts";
|
|
4
5
|
export { getAuthUser, redirectToLogin, handleCallback, getClientIP, checkBearerToken } from "./middleware.ts";
|
|
5
6
|
|
|
6
7
|
import { importPublicKey } from "./token.ts";
|
package/src/hono.ts
CHANGED
|
@@ -28,9 +28,6 @@ interface AuthOptions {
|
|
|
28
28
|
|
|
29
29
|
/** Cookie/token max age in seconds. Defaults to 86400 (24h). */
|
|
30
30
|
maxAge?: number;
|
|
31
|
-
|
|
32
|
-
/** Redirect callback mode. "code" avoids putting signed tokens in URLs. Defaults to "code". */
|
|
33
|
-
responseType?: "code" | "token";
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
const DEFAULT_AUTH_URL = "https://auth.uln.industries";
|
|
@@ -139,7 +136,7 @@ async function exchangeCodeWithBinding(code: string, redirectOrigin: string, bin
|
|
|
139
136
|
/**
|
|
140
137
|
* Hono middleware that handles the full auth flow:
|
|
141
138
|
*
|
|
142
|
-
* 1. If `?
|
|
139
|
+
* 1. If `?code=` in URL → exchange for token, set cookie, redirect to clean URL
|
|
143
140
|
* 2. If session cookie present → validate, set `c.get("user")`
|
|
144
141
|
* 3. If unauthenticated → redirect to auth.uln.industries/login
|
|
145
142
|
*
|
|
@@ -164,7 +161,6 @@ export function auth(options?: AuthOptions): MiddlewareHandler {
|
|
|
164
161
|
const authUrl = options?.authUrl ?? DEFAULT_AUTH_URL;
|
|
165
162
|
const cookieName = options?.cookie ?? DEFAULT_COOKIE;
|
|
166
163
|
const maxAge = options?.maxAge ?? DEFAULT_MAX_AGE;
|
|
167
|
-
const responseType = options?.responseType ?? "code";
|
|
168
164
|
const publicPaths = options?.public ?? [];
|
|
169
165
|
const bindingName = options?.binding;
|
|
170
166
|
|
|
@@ -200,7 +196,7 @@ export function auth(options?: AuthOptions): MiddlewareHandler {
|
|
|
200
196
|
return next();
|
|
201
197
|
}
|
|
202
198
|
|
|
203
|
-
// Step 1: Handle ?code= callback (
|
|
199
|
+
// Step 1: Handle ?code= callback (login redirect landing)
|
|
204
200
|
const incomingCode = url.searchParams.get("code");
|
|
205
201
|
if (incomingCode) {
|
|
206
202
|
const token = await exchangeCode(incomingCode, url.origin, c.env as Record<string, unknown>);
|
|
@@ -222,26 +218,7 @@ export function auth(options?: AuthOptions): MiddlewareHandler {
|
|
|
222
218
|
});
|
|
223
219
|
}
|
|
224
220
|
|
|
225
|
-
// Step 2:
|
|
226
|
-
const incomingToken = url.searchParams.get("token");
|
|
227
|
-
if (incomingToken) {
|
|
228
|
-
const payload = await validate(incomingToken, c.env as Record<string, unknown>);
|
|
229
|
-
if (!payload) {
|
|
230
|
-
return c.text("Invalid token", 401);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// Set cookie and redirect to clean URL (strip token param)
|
|
234
|
-
url.searchParams.delete("token");
|
|
235
|
-
return new Response(null, {
|
|
236
|
-
status: 302,
|
|
237
|
-
headers: {
|
|
238
|
-
Location: url.toString(),
|
|
239
|
-
"Set-Cookie": makeSessionCookie(cookieConf, incomingToken),
|
|
240
|
-
},
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Step 3: Check session cookie
|
|
221
|
+
// Step 2: Check session cookie
|
|
245
222
|
const cookieHeader = c.req.header("Cookie");
|
|
246
223
|
if (cookieHeader) {
|
|
247
224
|
const token = extractCookie(cookieHeader, cookieName);
|
|
@@ -269,7 +246,7 @@ export function auth(options?: AuthOptions): MiddlewareHandler {
|
|
|
269
246
|
// Step 5: Redirect to login
|
|
270
247
|
const loginUrl = new URL("/login", authUrl);
|
|
271
248
|
loginUrl.searchParams.set("redirect", c.req.url);
|
|
272
|
-
|
|
249
|
+
loginUrl.searchParams.set("response_type", "code");
|
|
273
250
|
return c.redirect(loginUrl.toString(), 302);
|
|
274
251
|
};
|
|
275
252
|
}
|
package/src/middleware.ts
CHANGED
|
@@ -33,10 +33,10 @@ export async function getAuthUser(
|
|
|
33
33
|
return validateToken(verifyConfig, token);
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export function redirectToLogin(currentUrl: string
|
|
36
|
+
export function redirectToLogin(currentUrl: string): Response {
|
|
37
37
|
const loginUrl = new URL("/login", "https://auth.uln.industries");
|
|
38
38
|
loginUrl.searchParams.set("redirect", currentUrl);
|
|
39
|
-
|
|
39
|
+
loginUrl.searchParams.set("response_type", "code");
|
|
40
40
|
return Response.redirect(loginUrl.toString(), 302);
|
|
41
41
|
}
|
|
42
42
|
|
|
@@ -57,8 +57,8 @@ async function exchangeCode(
|
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* Handle the auth callback on consuming sites.
|
|
60
|
-
* If the request URL has a `?code=`
|
|
61
|
-
* and redirects to the same URL without the
|
|
60
|
+
* If the request URL has a `?code=` param, exchanges it for a token,
|
|
61
|
+
* sets a session cookie, and redirects to the same URL without the code param.
|
|
62
62
|
* Returns null if there's no callback param.
|
|
63
63
|
*/
|
|
64
64
|
export async function handleCallback(
|
|
@@ -73,10 +73,10 @@ export async function handleCallback(
|
|
|
73
73
|
if (!exchangeConfig) return redirectToLogin(url.origin);
|
|
74
74
|
|
|
75
75
|
const token = await exchangeCode(code, url.origin, exchangeConfig);
|
|
76
|
-
if (!token) return redirectToLogin(url.origin
|
|
76
|
+
if (!token) return redirectToLogin(url.origin);
|
|
77
77
|
|
|
78
78
|
const payload = await validateToken(verifyConfig, token);
|
|
79
|
-
if (!payload) return redirectToLogin(url.origin
|
|
79
|
+
if (!payload) return redirectToLogin(url.origin);
|
|
80
80
|
|
|
81
81
|
url.searchParams.delete("code");
|
|
82
82
|
return new Response(null, {
|
|
@@ -88,20 +88,5 @@ export async function handleCallback(
|
|
|
88
88
|
});
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
-
|
|
92
|
-
if (!token) return null;
|
|
93
|
-
|
|
94
|
-
const payload = await validateToken(verifyConfig, token);
|
|
95
|
-
if (!payload) {
|
|
96
|
-
return redirectToLogin(url.origin);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
url.searchParams.delete("token");
|
|
100
|
-
return new Response(null, {
|
|
101
|
-
status: 302,
|
|
102
|
-
headers: {
|
|
103
|
-
Location: url.toString(),
|
|
104
|
-
"Set-Cookie": makeSessionCookie(cookieConfig, token),
|
|
105
|
-
},
|
|
106
|
-
});
|
|
91
|
+
return null;
|
|
107
92
|
}
|
package/src/service.ts
CHANGED
|
@@ -58,12 +58,12 @@ export async function getAuthUser(
|
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* Redirect to the centralized login page at auth.uln.industries.
|
|
61
|
-
* Requests one-time auth-code callbacks
|
|
61
|
+
* Requests one-time auth-code callbacks so signed tokens are not sent through URLs.
|
|
62
62
|
*/
|
|
63
|
-
export function redirectToLogin(currentUrl: string
|
|
63
|
+
export function redirectToLogin(currentUrl: string): Response {
|
|
64
64
|
const loginUrl = new URL("/login", "https://auth.uln.industries");
|
|
65
65
|
loginUrl.searchParams.set("redirect", currentUrl);
|
|
66
|
-
|
|
66
|
+
loginUrl.searchParams.set("response_type", "code");
|
|
67
67
|
return Response.redirect(loginUrl.toString(), 302);
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -81,7 +81,6 @@ async function exchangeCode(authService: Fetcher, code: string, redirectOrigin:
|
|
|
81
81
|
/**
|
|
82
82
|
* Handle an auth callback on a consuming Worker using the auth service binding.
|
|
83
83
|
* Preferred `?code=` callbacks are exchanged for signed tokens before setting the local cookie.
|
|
84
|
-
* Legacy `?token=` callbacks are still accepted during migration and are stripped immediately.
|
|
85
84
|
* Returns null if the request has no auth callback parameters.
|
|
86
85
|
*/
|
|
87
86
|
export async function handleCallback(
|
|
@@ -94,10 +93,10 @@ export async function handleCallback(
|
|
|
94
93
|
const code = url.searchParams.get("code");
|
|
95
94
|
if (code) {
|
|
96
95
|
const token = await exchangeCode(authService, code, url.origin);
|
|
97
|
-
if (!token) return redirectToLogin(url.origin
|
|
96
|
+
if (!token) return redirectToLogin(url.origin);
|
|
98
97
|
|
|
99
98
|
const payload = await verifyToken(authService, token);
|
|
100
|
-
if (!payload) return redirectToLogin(url.origin
|
|
99
|
+
if (!payload) return redirectToLogin(url.origin);
|
|
101
100
|
|
|
102
101
|
url.searchParams.delete("code");
|
|
103
102
|
return new Response(null, {
|
|
@@ -109,18 +108,5 @@ export async function handleCallback(
|
|
|
109
108
|
});
|
|
110
109
|
}
|
|
111
110
|
|
|
112
|
-
|
|
113
|
-
if (!token) return null;
|
|
114
|
-
|
|
115
|
-
const payload = await verifyToken(authService, token);
|
|
116
|
-
if (!payload) return redirectToLogin(url.origin, "code");
|
|
117
|
-
|
|
118
|
-
url.searchParams.delete("token");
|
|
119
|
-
return new Response(null, {
|
|
120
|
-
status: 302,
|
|
121
|
-
headers: {
|
|
122
|
-
Location: url.toString(),
|
|
123
|
-
"Set-Cookie": makeSessionCookie(cookieConfig, token),
|
|
124
|
-
},
|
|
125
|
-
});
|
|
111
|
+
return null;
|
|
126
112
|
}
|