mailsentry-auth 0.2.6 → 0.2.8
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/index.d.mts +34 -24
- package/dist/index.d.ts +34 -24
- package/dist/index.js +147 -110
- package/dist/index.mjs +148 -111
- package/dist/middleware.d.mts +2 -5
- package/dist/middleware.mjs +139 -77
- package/dist/utils/cookie-utils.js +51 -33
- package/dist/utils/cookie-utils.mjs +51 -33
- package/package.json +1 -1
package/dist/middleware.mjs
CHANGED
|
@@ -4,18 +4,54 @@ import Cookies from 'js-cookie';
|
|
|
4
4
|
// src/middlewares/handlers/base-middleware-handler.ts
|
|
5
5
|
|
|
6
6
|
// src/config/middleware.ts
|
|
7
|
-
var
|
|
8
|
-
// Route Protection Configuration
|
|
9
|
-
// PATTERNS_TO_PROTECT: Routes that require authentication (whitelist approach recommended for security)
|
|
10
|
-
// PATTERNS_TO_EXCLUDE: Routes to explicitly exclude from protection (e.g., login page, public assets)
|
|
7
|
+
var MiddlewareConfig = class {
|
|
11
8
|
/**
|
|
12
|
-
* Get
|
|
13
|
-
*
|
|
9
|
+
* Get dynamic protection rules from environment variable
|
|
10
|
+
* Format: "host:path" or "path"
|
|
14
11
|
*/
|
|
15
|
-
static
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
static getProtectedRules() {
|
|
13
|
+
return this.parseRules(process.env.NEXT_PUBLIC_PROTECTED_ROUTES, [
|
|
14
|
+
{ hostPattern: this.CONSTANTS.DASHBOARD_SUBDOMAIN, pathPattern: "*" }
|
|
15
|
+
]);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Get public routes whitelist (Exclusions)
|
|
19
|
+
* Format: "host:path" or "path"
|
|
20
|
+
*/
|
|
21
|
+
static getWhitelistRules() {
|
|
22
|
+
return this.parseRules(process.env.NEXT_PUBLIC_AUTH_WHITELIST_ROUTES, [
|
|
23
|
+
{ hostPattern: null, pathPattern: this.CONSTANTS.LOGIN_PATH }
|
|
24
|
+
]);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get guest-only routes (redirects authenticated users away)
|
|
28
|
+
* Format: "host:path" or "path"
|
|
29
|
+
*/
|
|
30
|
+
static getGuestOnlyRules() {
|
|
31
|
+
return this.parseRules(process.env.NEXT_PUBLIC_GUEST_ONLY_ROUTES, [
|
|
32
|
+
{ hostPattern: null, pathPattern: this.CONSTANTS.LOGIN_PATH }
|
|
33
|
+
]);
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Generic parser for environment variables containing rule lists
|
|
37
|
+
*/
|
|
38
|
+
static parseRules(envVar, defaults) {
|
|
39
|
+
if (envVar === void 0) return defaults;
|
|
40
|
+
return envVar.split(",").map((rule) => this.parseSingleRule(rule)).filter((r) => r.pathPattern.length > 0);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Parse a single rule string into a ProtectionRule object
|
|
44
|
+
*/
|
|
45
|
+
static parseSingleRule(ruleString) {
|
|
46
|
+
const trimmed = ruleString.trim();
|
|
47
|
+
const separatorIndex = trimmed.indexOf(":");
|
|
48
|
+
if (separatorIndex === -1) {
|
|
49
|
+
return { hostPattern: null, pathPattern: trimmed };
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
hostPattern: trimmed.substring(0, separatorIndex).trim(),
|
|
53
|
+
pathPattern: trimmed.substring(separatorIndex + 1).trim()
|
|
54
|
+
};
|
|
19
55
|
}
|
|
20
56
|
/**
|
|
21
57
|
* Get the base domain from environment or use default
|
|
@@ -31,41 +67,23 @@ var _MiddlewareConfig = class _MiddlewareConfig {
|
|
|
31
67
|
}
|
|
32
68
|
};
|
|
33
69
|
// Common constants
|
|
34
|
-
|
|
70
|
+
MiddlewareConfig.CONSTANTS = {
|
|
35
71
|
LOGIN_PATH: "/login",
|
|
36
|
-
DASHBOARD_SUBDOMAIN: "dashboard"
|
|
37
|
-
PUBLIC_PATH: "/public",
|
|
38
|
-
PUBLIC_API_PATH: "/api/public"
|
|
39
|
-
};
|
|
40
|
-
_MiddlewareConfig.PROTECTED_ROUTES = {
|
|
41
|
-
// Routes that MUST be protected
|
|
42
|
-
INCLUDE: [
|
|
43
|
-
"/"
|
|
44
|
-
// Protect everything by default (since dashboard.cutly.io/ is the root)
|
|
45
|
-
],
|
|
46
|
-
// Routes that should NEVER be protected (public)
|
|
47
|
-
EXCLUDE: [
|
|
48
|
-
_MiddlewareConfig.CONSTANTS.LOGIN_PATH,
|
|
49
|
-
_MiddlewareConfig.CONSTANTS.PUBLIC_PATH,
|
|
50
|
-
_MiddlewareConfig.CONSTANTS.PUBLIC_API_PATH,
|
|
51
|
-
..._MiddlewareConfig.getPublicRoutesWhitelist()
|
|
52
|
-
// Add custom whitelist from env
|
|
53
|
-
]
|
|
72
|
+
DASHBOARD_SUBDOMAIN: "dashboard"
|
|
54
73
|
};
|
|
55
74
|
// HTTP methods to process
|
|
56
|
-
|
|
75
|
+
MiddlewareConfig.ALLOWED_METHODS = ["GET", "HEAD"];
|
|
57
76
|
// Query parameters
|
|
58
|
-
|
|
77
|
+
MiddlewareConfig.QUERY_PARAMS = {
|
|
59
78
|
LOGIN_REQUIRED: "sign_in_required",
|
|
60
79
|
AUTH_CHECKED: "auth_checked",
|
|
61
80
|
REDIRECT_URL: "redirect_url"
|
|
62
81
|
};
|
|
63
82
|
// Query parameter values
|
|
64
|
-
|
|
83
|
+
MiddlewareConfig.QUERY_VALUES = {
|
|
65
84
|
LOGIN_REQUIRED: "true",
|
|
66
85
|
AUTH_CHECKED: "1"
|
|
67
86
|
};
|
|
68
|
-
var MiddlewareConfig = _MiddlewareConfig;
|
|
69
87
|
var middlewareMatcher = [
|
|
70
88
|
"/((?!api|_next/static|_next/image|_next/webpack-hmr|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|css|js)$).*)"
|
|
71
89
|
];
|
|
@@ -350,23 +368,83 @@ var _CookieUtils = class _CookieUtils {
|
|
|
350
368
|
_CookieUtils.COOKIE_DOMAIN = _CookieUtils.getRootDomain();
|
|
351
369
|
var CookieUtils = _CookieUtils;
|
|
352
370
|
|
|
371
|
+
// src/middlewares/utils/email-validator.ts
|
|
372
|
+
var isPublicUserEmail = (email) => {
|
|
373
|
+
if (!email || typeof email !== "string") return false;
|
|
374
|
+
const parts = email.split("@");
|
|
375
|
+
if (parts.length !== 2) return false;
|
|
376
|
+
const localPart = parts[0];
|
|
377
|
+
const ipv4Pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
|
378
|
+
const match = localPart.match(ipv4Pattern);
|
|
379
|
+
if (!match) return false;
|
|
380
|
+
for (let i = 1; i <= 4; i++) {
|
|
381
|
+
const octet = parseInt(match[i], 10);
|
|
382
|
+
if (octet < 0 || octet > 255) return false;
|
|
383
|
+
}
|
|
384
|
+
return true;
|
|
385
|
+
};
|
|
386
|
+
|
|
353
387
|
// src/middlewares/handlers/base-middleware-handler.ts
|
|
354
388
|
var BaseMiddlewareHandler = class {
|
|
355
389
|
/**
|
|
356
390
|
* Check if current route requires authentication
|
|
357
|
-
* Uses inclusive (PROTECTED_ROUTES.INCLUDE) and exclusive (PROTECTED_ROUTES.EXCLUDE) lists
|
|
358
391
|
*/
|
|
359
|
-
requiresAuthentication(pathname) {
|
|
360
|
-
|
|
361
|
-
(route) => pathname.startsWith(route) || pathname === route
|
|
362
|
-
);
|
|
363
|
-
if (isExcluded) {
|
|
392
|
+
requiresAuthentication(pathname, hostname) {
|
|
393
|
+
if (this.isExcludedRoute(pathname, hostname)) {
|
|
364
394
|
return false;
|
|
365
395
|
}
|
|
366
|
-
return MiddlewareConfig.
|
|
367
|
-
(
|
|
396
|
+
return MiddlewareConfig.getProtectedRules().some(
|
|
397
|
+
(rule) => this.isRuleMatch(rule, pathname, hostname)
|
|
368
398
|
);
|
|
369
399
|
}
|
|
400
|
+
/**
|
|
401
|
+
* Check if current route is guest-only (authenticated users should be redirected away)
|
|
402
|
+
*/
|
|
403
|
+
isGuestOnlyRoute(pathname, hostname) {
|
|
404
|
+
return MiddlewareConfig.getGuestOnlyRules().some(
|
|
405
|
+
(rule) => this.isRuleMatch(rule, pathname, hostname)
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Check if the route is explicitly excluded from authentication
|
|
410
|
+
*/
|
|
411
|
+
isExcludedRoute(pathname, hostname) {
|
|
412
|
+
return MiddlewareConfig.getWhitelistRules().some(
|
|
413
|
+
(rule) => this.isRuleMatch(rule, pathname, hostname)
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Check if a single protection rule matches the current request
|
|
418
|
+
*/
|
|
419
|
+
isRuleMatch(rule, pathname, hostname) {
|
|
420
|
+
if (rule.hostPattern && (!hostname || !hostname.startsWith(`${rule.hostPattern}.`) && hostname !== rule.hostPattern)) {
|
|
421
|
+
return false;
|
|
422
|
+
}
|
|
423
|
+
return rule.pathPattern === "*" || pathname === rule.pathPattern || pathname.startsWith(rule.pathPattern);
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Validates authentication and returns user info if valid
|
|
427
|
+
* Used by both AuthenticationHandler and GuestOnlyHandler to avoid duplication
|
|
428
|
+
*/
|
|
429
|
+
async getAuthenticatedUser(cookies) {
|
|
430
|
+
var _a, _b;
|
|
431
|
+
if (!this.hasAuthenticationCookies(cookies)) {
|
|
432
|
+
return null;
|
|
433
|
+
}
|
|
434
|
+
try {
|
|
435
|
+
const authResponse = await this.validateUserAuth(cookies);
|
|
436
|
+
if (!authResponse.ok) {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
const data = await authResponse.json();
|
|
440
|
+
const userEmail = ((_b = (_a = data == null ? void 0 : data.data) == null ? void 0 : _a.user) == null ? void 0 : _b.email) || "";
|
|
441
|
+
const isPublic = isPublicUserEmail(userEmail);
|
|
442
|
+
return { email: userEmail, isPublic };
|
|
443
|
+
} catch (error) {
|
|
444
|
+
console.log("Auth validation error:", error instanceof Error ? error.message : "Unknown error");
|
|
445
|
+
return null;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
370
448
|
/**
|
|
371
449
|
* Check if user has both access and refresh tokens
|
|
372
450
|
*/
|
|
@@ -478,26 +556,27 @@ var MethodFilterHandler = class extends BaseMiddlewareHandler {
|
|
|
478
556
|
return this.continue();
|
|
479
557
|
}
|
|
480
558
|
};
|
|
481
|
-
|
|
482
|
-
// src/middlewares/handlers/authentication-handler.ts
|
|
483
559
|
var AuthenticationHandler = class extends BaseMiddlewareHandler {
|
|
484
560
|
async handle(context) {
|
|
485
|
-
|
|
486
|
-
const { cookies, pathname } = context;
|
|
487
|
-
if (!this.requiresAuthentication(pathname)) {
|
|
488
|
-
return this.continue();
|
|
489
|
-
}
|
|
490
|
-
const hasAuthCookies = this.hasAuthenticationCookies(cookies);
|
|
491
|
-
if (!hasAuthCookies) {
|
|
492
|
-
return this.addLoginModalParams(context);
|
|
493
|
-
}
|
|
561
|
+
const { cookies, pathname, hostname } = context;
|
|
494
562
|
try {
|
|
495
|
-
const
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
563
|
+
const isGuestOnly = this.isGuestOnlyRoute(pathname, hostname);
|
|
564
|
+
const isProtected = this.requiresAuthentication(pathname, hostname);
|
|
565
|
+
if (!isGuestOnly && !isProtected) {
|
|
566
|
+
return this.continue();
|
|
567
|
+
}
|
|
568
|
+
const user = this.hasAuthenticationCookies(cookies) ? await this.getAuthenticatedUser(cookies) : null;
|
|
569
|
+
if (isGuestOnly) {
|
|
570
|
+
if (user && !user.isPublic) {
|
|
571
|
+
return NextResponse.redirect(new URL("/", context.request.url));
|
|
572
|
+
}
|
|
573
|
+
return this.continue();
|
|
574
|
+
}
|
|
575
|
+
if (isProtected) {
|
|
576
|
+
if (!user) {
|
|
577
|
+
return this.addLoginModalParams(context);
|
|
578
|
+
}
|
|
579
|
+
if (user.isPublic) {
|
|
501
580
|
console.log("Public session user detected (IP-based email) - requiring authentication");
|
|
502
581
|
return this.addLoginModalParams(context);
|
|
503
582
|
}
|
|
@@ -506,10 +585,9 @@ var AuthenticationHandler = class extends BaseMiddlewareHandler {
|
|
|
506
585
|
}
|
|
507
586
|
return this.allow();
|
|
508
587
|
}
|
|
509
|
-
|
|
510
|
-
return this.addLoginModalParams(context);
|
|
588
|
+
return this.continue();
|
|
511
589
|
} catch (error) {
|
|
512
|
-
console.
|
|
590
|
+
console.error("AuthenticationHandler error:", error);
|
|
513
591
|
return this.addLoginModalParams(context);
|
|
514
592
|
}
|
|
515
593
|
}
|
|
@@ -533,22 +611,6 @@ var MiddlewareChain = class {
|
|
|
533
611
|
}
|
|
534
612
|
};
|
|
535
613
|
|
|
536
|
-
// src/middlewares/utils/email-validator.ts
|
|
537
|
-
var isPublicUserEmail = (email) => {
|
|
538
|
-
if (!email || typeof email !== "string") return false;
|
|
539
|
-
const parts = email.split("@");
|
|
540
|
-
if (parts.length !== 2) return false;
|
|
541
|
-
const localPart = parts[0];
|
|
542
|
-
const ipv4Pattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
|
|
543
|
-
const match = localPart.match(ipv4Pattern);
|
|
544
|
-
if (!match) return false;
|
|
545
|
-
for (let i = 1; i <= 4; i++) {
|
|
546
|
-
const octet = parseInt(match[i], 10);
|
|
547
|
-
if (octet < 0 || octet > 255) return false;
|
|
548
|
-
}
|
|
549
|
-
return true;
|
|
550
|
-
};
|
|
551
|
-
|
|
552
614
|
// src/middleware.ts
|
|
553
615
|
async function middleware(req) {
|
|
554
616
|
const hostname = req.headers.get("host") || req.nextUrl.hostname;
|
|
@@ -2,18 +2,54 @@
|
|
|
2
2
|
var _jscookie = require('js-cookie'); var _jscookie2 = _interopRequireDefault(_jscookie);
|
|
3
3
|
|
|
4
4
|
// src/config/middleware.ts
|
|
5
|
-
var
|
|
6
|
-
// Route Protection Configuration
|
|
7
|
-
// PATTERNS_TO_PROTECT: Routes that require authentication (whitelist approach recommended for security)
|
|
8
|
-
// PATTERNS_TO_EXCLUDE: Routes to explicitly exclude from protection (e.g., login page, public assets)
|
|
5
|
+
var MiddlewareConfig = class {
|
|
9
6
|
/**
|
|
10
|
-
* Get
|
|
11
|
-
*
|
|
7
|
+
* Get dynamic protection rules from environment variable
|
|
8
|
+
* Format: "host:path" or "path"
|
|
12
9
|
*/
|
|
13
|
-
static
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
static getProtectedRules() {
|
|
11
|
+
return this.parseRules(process.env.NEXT_PUBLIC_PROTECTED_ROUTES, [
|
|
12
|
+
{ hostPattern: this.CONSTANTS.DASHBOARD_SUBDOMAIN, pathPattern: "*" }
|
|
13
|
+
]);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get public routes whitelist (Exclusions)
|
|
17
|
+
* Format: "host:path" or "path"
|
|
18
|
+
*/
|
|
19
|
+
static getWhitelistRules() {
|
|
20
|
+
return this.parseRules(process.env.NEXT_PUBLIC_AUTH_WHITELIST_ROUTES, [
|
|
21
|
+
{ hostPattern: null, pathPattern: this.CONSTANTS.LOGIN_PATH }
|
|
22
|
+
]);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get guest-only routes (redirects authenticated users away)
|
|
26
|
+
* Format: "host:path" or "path"
|
|
27
|
+
*/
|
|
28
|
+
static getGuestOnlyRules() {
|
|
29
|
+
return this.parseRules(process.env.NEXT_PUBLIC_GUEST_ONLY_ROUTES, [
|
|
30
|
+
{ hostPattern: null, pathPattern: this.CONSTANTS.LOGIN_PATH }
|
|
31
|
+
]);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Generic parser for environment variables containing rule lists
|
|
35
|
+
*/
|
|
36
|
+
static parseRules(envVar, defaults) {
|
|
37
|
+
if (envVar === void 0) return defaults;
|
|
38
|
+
return envVar.split(",").map((rule) => this.parseSingleRule(rule)).filter((r) => r.pathPattern.length > 0);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse a single rule string into a ProtectionRule object
|
|
42
|
+
*/
|
|
43
|
+
static parseSingleRule(ruleString) {
|
|
44
|
+
const trimmed = ruleString.trim();
|
|
45
|
+
const separatorIndex = trimmed.indexOf(":");
|
|
46
|
+
if (separatorIndex === -1) {
|
|
47
|
+
return { hostPattern: null, pathPattern: trimmed };
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
hostPattern: trimmed.substring(0, separatorIndex).trim(),
|
|
51
|
+
pathPattern: trimmed.substring(separatorIndex + 1).trim()
|
|
52
|
+
};
|
|
17
53
|
}
|
|
18
54
|
/**
|
|
19
55
|
* Get the base domain from environment or use default
|
|
@@ -29,41 +65,23 @@ var _MiddlewareConfig = class _MiddlewareConfig {
|
|
|
29
65
|
}
|
|
30
66
|
};
|
|
31
67
|
// Common constants
|
|
32
|
-
|
|
68
|
+
MiddlewareConfig.CONSTANTS = {
|
|
33
69
|
LOGIN_PATH: "/login",
|
|
34
|
-
DASHBOARD_SUBDOMAIN: "dashboard"
|
|
35
|
-
PUBLIC_PATH: "/public",
|
|
36
|
-
PUBLIC_API_PATH: "/api/public"
|
|
37
|
-
};
|
|
38
|
-
_MiddlewareConfig.PROTECTED_ROUTES = {
|
|
39
|
-
// Routes that MUST be protected
|
|
40
|
-
INCLUDE: [
|
|
41
|
-
"/"
|
|
42
|
-
// Protect everything by default (since dashboard.cutly.io/ is the root)
|
|
43
|
-
],
|
|
44
|
-
// Routes that should NEVER be protected (public)
|
|
45
|
-
EXCLUDE: [
|
|
46
|
-
_MiddlewareConfig.CONSTANTS.LOGIN_PATH,
|
|
47
|
-
_MiddlewareConfig.CONSTANTS.PUBLIC_PATH,
|
|
48
|
-
_MiddlewareConfig.CONSTANTS.PUBLIC_API_PATH,
|
|
49
|
-
..._MiddlewareConfig.getPublicRoutesWhitelist()
|
|
50
|
-
// Add custom whitelist from env
|
|
51
|
-
]
|
|
70
|
+
DASHBOARD_SUBDOMAIN: "dashboard"
|
|
52
71
|
};
|
|
53
72
|
// HTTP methods to process
|
|
54
|
-
|
|
73
|
+
MiddlewareConfig.ALLOWED_METHODS = ["GET", "HEAD"];
|
|
55
74
|
// Query parameters
|
|
56
|
-
|
|
75
|
+
MiddlewareConfig.QUERY_PARAMS = {
|
|
57
76
|
LOGIN_REQUIRED: "sign_in_required",
|
|
58
77
|
AUTH_CHECKED: "auth_checked",
|
|
59
78
|
REDIRECT_URL: "redirect_url"
|
|
60
79
|
};
|
|
61
80
|
// Query parameter values
|
|
62
|
-
|
|
81
|
+
MiddlewareConfig.QUERY_VALUES = {
|
|
63
82
|
LOGIN_REQUIRED: "true",
|
|
64
83
|
AUTH_CHECKED: "1"
|
|
65
84
|
};
|
|
66
|
-
var MiddlewareConfig = _MiddlewareConfig;
|
|
67
85
|
|
|
68
86
|
// src/services/utils/url-utils.ts
|
|
69
87
|
var UrlUtils = class {
|
|
@@ -2,18 +2,54 @@
|
|
|
2
2
|
import Cookies from "js-cookie";
|
|
3
3
|
|
|
4
4
|
// src/config/middleware.ts
|
|
5
|
-
var
|
|
6
|
-
// Route Protection Configuration
|
|
7
|
-
// PATTERNS_TO_PROTECT: Routes that require authentication (whitelist approach recommended for security)
|
|
8
|
-
// PATTERNS_TO_EXCLUDE: Routes to explicitly exclude from protection (e.g., login page, public assets)
|
|
5
|
+
var MiddlewareConfig = class {
|
|
9
6
|
/**
|
|
10
|
-
* Get
|
|
11
|
-
*
|
|
7
|
+
* Get dynamic protection rules from environment variable
|
|
8
|
+
* Format: "host:path" or "path"
|
|
12
9
|
*/
|
|
13
|
-
static
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
static getProtectedRules() {
|
|
11
|
+
return this.parseRules(process.env.NEXT_PUBLIC_PROTECTED_ROUTES, [
|
|
12
|
+
{ hostPattern: this.CONSTANTS.DASHBOARD_SUBDOMAIN, pathPattern: "*" }
|
|
13
|
+
]);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get public routes whitelist (Exclusions)
|
|
17
|
+
* Format: "host:path" or "path"
|
|
18
|
+
*/
|
|
19
|
+
static getWhitelistRules() {
|
|
20
|
+
return this.parseRules(process.env.NEXT_PUBLIC_AUTH_WHITELIST_ROUTES, [
|
|
21
|
+
{ hostPattern: null, pathPattern: this.CONSTANTS.LOGIN_PATH }
|
|
22
|
+
]);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get guest-only routes (redirects authenticated users away)
|
|
26
|
+
* Format: "host:path" or "path"
|
|
27
|
+
*/
|
|
28
|
+
static getGuestOnlyRules() {
|
|
29
|
+
return this.parseRules(process.env.NEXT_PUBLIC_GUEST_ONLY_ROUTES, [
|
|
30
|
+
{ hostPattern: null, pathPattern: this.CONSTANTS.LOGIN_PATH }
|
|
31
|
+
]);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Generic parser for environment variables containing rule lists
|
|
35
|
+
*/
|
|
36
|
+
static parseRules(envVar, defaults) {
|
|
37
|
+
if (envVar === void 0) return defaults;
|
|
38
|
+
return envVar.split(",").map((rule) => this.parseSingleRule(rule)).filter((r) => r.pathPattern.length > 0);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse a single rule string into a ProtectionRule object
|
|
42
|
+
*/
|
|
43
|
+
static parseSingleRule(ruleString) {
|
|
44
|
+
const trimmed = ruleString.trim();
|
|
45
|
+
const separatorIndex = trimmed.indexOf(":");
|
|
46
|
+
if (separatorIndex === -1) {
|
|
47
|
+
return { hostPattern: null, pathPattern: trimmed };
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
hostPattern: trimmed.substring(0, separatorIndex).trim(),
|
|
51
|
+
pathPattern: trimmed.substring(separatorIndex + 1).trim()
|
|
52
|
+
};
|
|
17
53
|
}
|
|
18
54
|
/**
|
|
19
55
|
* Get the base domain from environment or use default
|
|
@@ -29,41 +65,23 @@ var _MiddlewareConfig = class _MiddlewareConfig {
|
|
|
29
65
|
}
|
|
30
66
|
};
|
|
31
67
|
// Common constants
|
|
32
|
-
|
|
68
|
+
MiddlewareConfig.CONSTANTS = {
|
|
33
69
|
LOGIN_PATH: "/login",
|
|
34
|
-
DASHBOARD_SUBDOMAIN: "dashboard"
|
|
35
|
-
PUBLIC_PATH: "/public",
|
|
36
|
-
PUBLIC_API_PATH: "/api/public"
|
|
37
|
-
};
|
|
38
|
-
_MiddlewareConfig.PROTECTED_ROUTES = {
|
|
39
|
-
// Routes that MUST be protected
|
|
40
|
-
INCLUDE: [
|
|
41
|
-
"/"
|
|
42
|
-
// Protect everything by default (since dashboard.cutly.io/ is the root)
|
|
43
|
-
],
|
|
44
|
-
// Routes that should NEVER be protected (public)
|
|
45
|
-
EXCLUDE: [
|
|
46
|
-
_MiddlewareConfig.CONSTANTS.LOGIN_PATH,
|
|
47
|
-
_MiddlewareConfig.CONSTANTS.PUBLIC_PATH,
|
|
48
|
-
_MiddlewareConfig.CONSTANTS.PUBLIC_API_PATH,
|
|
49
|
-
..._MiddlewareConfig.getPublicRoutesWhitelist()
|
|
50
|
-
// Add custom whitelist from env
|
|
51
|
-
]
|
|
70
|
+
DASHBOARD_SUBDOMAIN: "dashboard"
|
|
52
71
|
};
|
|
53
72
|
// HTTP methods to process
|
|
54
|
-
|
|
73
|
+
MiddlewareConfig.ALLOWED_METHODS = ["GET", "HEAD"];
|
|
55
74
|
// Query parameters
|
|
56
|
-
|
|
75
|
+
MiddlewareConfig.QUERY_PARAMS = {
|
|
57
76
|
LOGIN_REQUIRED: "sign_in_required",
|
|
58
77
|
AUTH_CHECKED: "auth_checked",
|
|
59
78
|
REDIRECT_URL: "redirect_url"
|
|
60
79
|
};
|
|
61
80
|
// Query parameter values
|
|
62
|
-
|
|
81
|
+
MiddlewareConfig.QUERY_VALUES = {
|
|
63
82
|
LOGIN_REQUIRED: "true",
|
|
64
83
|
AUTH_CHECKED: "1"
|
|
65
84
|
};
|
|
66
|
-
var MiddlewareConfig = _MiddlewareConfig;
|
|
67
85
|
|
|
68
86
|
// src/services/utils/url-utils.ts
|
|
69
87
|
var UrlUtils = class {
|
package/package.json
CHANGED