@open-mercato/core 0.4.2-canary-22a467da89 → 0.4.2-canary-a8ae8aa761
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.
|
@@ -8,9 +8,22 @@ function parseCookie(req, name) {
|
|
|
8
8
|
const m = cookie.match(new RegExp("(?:^|;\\s*)" + name + "=([^;]+)"));
|
|
9
9
|
return m ? decodeURIComponent(m[1]) : null;
|
|
10
10
|
}
|
|
11
|
+
function sanitizeRedirect(param, baseUrl) {
|
|
12
|
+
const value = param || "/";
|
|
13
|
+
try {
|
|
14
|
+
const base = new URL(baseUrl);
|
|
15
|
+
const resolved = new URL(value, baseUrl);
|
|
16
|
+
if (resolved.origin === base.origin && resolved.pathname.startsWith("/")) {
|
|
17
|
+
return resolved.pathname + resolved.search + resolved.hash;
|
|
18
|
+
}
|
|
19
|
+
} catch {
|
|
20
|
+
}
|
|
21
|
+
return "/";
|
|
22
|
+
}
|
|
11
23
|
async function GET(req) {
|
|
12
24
|
const url = new URL(req.url);
|
|
13
|
-
const
|
|
25
|
+
const baseUrl = process.env.APP_URL || `${url.protocol}//${url.host}`;
|
|
26
|
+
const redirectTo = sanitizeRedirect(url.searchParams.get("redirect"), baseUrl);
|
|
14
27
|
const token = parseCookie(req, "session_token");
|
|
15
28
|
if (!token) return NextResponse.redirect(toAbsoluteUrl(req, "/login?redirect=" + encodeURIComponent(redirectTo)));
|
|
16
29
|
const c = await createRequestContainer();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../src/modules/auth/api/session/refresh.ts"],
|
|
4
|
-
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { toAbsoluteUrl } from '@open-mercato/shared/lib/url'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { AuthService } from '@open-mercato/core/modules/auth/services/authService'\nimport { signJwt } from '@open-mercato/shared/lib/auth/jwt'\nimport { z } from 'zod'\n\nfunction parseCookie(req: Request, name: string): string | null {\n const cookie = req.headers.get('cookie') || ''\n const m = cookie.match(new RegExp('(?:^|;\\\\s*)' + name + '=([^;]+)'))\n return m ? decodeURIComponent(m[1]) : null\n}\n\nexport async function GET(req: Request) {\n const url = new URL(req.url)\n const redirectTo = url.searchParams.get('redirect')
|
|
5
|
-
"mappings": "AAAA,SAAS,oBAAoB;AAE7B,SAAS,qBAAqB;AAC9B,SAAS,8BAA8B;AAEvC,SAAS,eAAe;AACxB,SAAS,SAAS;AAElB,SAAS,YAAY,KAAc,MAA6B;AAC9D,QAAM,SAAS,IAAI,QAAQ,IAAI,QAAQ,KAAK;AAC5C,QAAM,IAAI,OAAO,MAAM,IAAI,OAAO,gBAAgB,OAAO,UAAU,CAAC;AACpE,SAAO,IAAI,mBAAmB,EAAE,CAAC,CAAC,IAAI;AACxC;AAEA,eAAsB,IAAI,KAAc;AACtC,QAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,QAAM,aAAa,IAAI,aAAa,IAAI,UAAU,
|
|
4
|
+
"sourcesContent": ["import { NextResponse } from 'next/server'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { toAbsoluteUrl } from '@open-mercato/shared/lib/url'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { AuthService } from '@open-mercato/core/modules/auth/services/authService'\nimport { signJwt } from '@open-mercato/shared/lib/auth/jwt'\nimport { z } from 'zod'\n\nfunction parseCookie(req: Request, name: string): string | null {\n const cookie = req.headers.get('cookie') || ''\n const m = cookie.match(new RegExp('(?:^|;\\\\s*)' + name + '=([^;]+)'))\n return m ? decodeURIComponent(m[1]) : null\n}\n\nfunction sanitizeRedirect(param: string | null, baseUrl: string): string {\n const value = param || '/'\n try {\n const base = new URL(baseUrl)\n const resolved = new URL(value, baseUrl)\n if (resolved.origin === base.origin && resolved.pathname.startsWith('/')) {\n return resolved.pathname + resolved.search + resolved.hash\n }\n } catch {}\n return '/'\n}\n\nexport async function GET(req: Request) {\n const url = new URL(req.url)\n const baseUrl = process.env.APP_URL || `${url.protocol}//${url.host}`\n const redirectTo = sanitizeRedirect(url.searchParams.get('redirect'), baseUrl)\n const token = parseCookie(req, 'session_token')\n if (!token) return NextResponse.redirect(toAbsoluteUrl(req, '/login?redirect=' + encodeURIComponent(redirectTo)))\n const c = await createRequestContainer()\n const auth = c.resolve<AuthService>('authService')\n const ctx = await auth.refreshFromSessionToken(token)\n if (!ctx) return NextResponse.redirect(toAbsoluteUrl(req, '/login?redirect=' + encodeURIComponent(redirectTo)))\n const { user, roles } = ctx\n const jwt = signJwt({ sub: String(user.id), tenantId: String(user.tenantId), orgId: String(user.organizationId), email: user.email, roles })\n const res = NextResponse.redirect(toAbsoluteUrl(req, redirectTo))\n res.cookies.set('auth_token', jwt, { httpOnly: true, path: '/', sameSite: 'lax', secure: process.env.NODE_ENV === 'production', maxAge: 60 * 60 * 8 })\n return res\n}\n\nexport const metadata = {\n GET: { requireAuth: false },\n}\n\nconst refreshQuerySchema = z.object({\n redirect: z.string().optional().describe('Absolute or relative URL to redirect after refresh'),\n})\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Authentication & Accounts',\n summary: 'Refresh session token',\n methods: {\n GET: {\n summary: 'Refresh auth cookie from session token',\n description: 'Exchanges an existing `session_token` cookie for a fresh JWT auth cookie and redirects the browser.',\n query: refreshQuerySchema,\n responses: [\n { status: 302, description: 'Redirect to target location when session is valid', mediaType: 'text/html' },\n ],\n },\n },\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,oBAAoB;AAE7B,SAAS,qBAAqB;AAC9B,SAAS,8BAA8B;AAEvC,SAAS,eAAe;AACxB,SAAS,SAAS;AAElB,SAAS,YAAY,KAAc,MAA6B;AAC9D,QAAM,SAAS,IAAI,QAAQ,IAAI,QAAQ,KAAK;AAC5C,QAAM,IAAI,OAAO,MAAM,IAAI,OAAO,gBAAgB,OAAO,UAAU,CAAC;AACpE,SAAO,IAAI,mBAAmB,EAAE,CAAC,CAAC,IAAI;AACxC;AAEA,SAAS,iBAAiB,OAAsB,SAAyB;AACvE,QAAM,QAAQ,SAAS;AACvB,MAAI;AACF,UAAM,OAAO,IAAI,IAAI,OAAO;AAC5B,UAAM,WAAW,IAAI,IAAI,OAAO,OAAO;AACvC,QAAI,SAAS,WAAW,KAAK,UAAU,SAAS,SAAS,WAAW,GAAG,GAAG;AACxE,aAAO,SAAS,WAAW,SAAS,SAAS,SAAS;AAAA,IACxD;AAAA,EACF,QAAQ;AAAA,EAAC;AACT,SAAO;AACT;AAEA,eAAsB,IAAI,KAAc;AACtC,QAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,QAAM,UAAU,QAAQ,IAAI,WAAW,GAAG,IAAI,QAAQ,KAAK,IAAI,IAAI;AACnE,QAAM,aAAa,iBAAiB,IAAI,aAAa,IAAI,UAAU,GAAG,OAAO;AAC7E,QAAM,QAAQ,YAAY,KAAK,eAAe;AAC9C,MAAI,CAAC,MAAO,QAAO,aAAa,SAAS,cAAc,KAAK,qBAAqB,mBAAmB,UAAU,CAAC,CAAC;AAChH,QAAM,IAAI,MAAM,uBAAuB;AACvC,QAAM,OAAO,EAAE,QAAqB,aAAa;AACjD,QAAM,MAAM,MAAM,KAAK,wBAAwB,KAAK;AACpD,MAAI,CAAC,IAAK,QAAO,aAAa,SAAS,cAAc,KAAK,qBAAqB,mBAAmB,UAAU,CAAC,CAAC;AAC9G,QAAM,EAAE,MAAM,MAAM,IAAI;AACxB,QAAM,MAAM,QAAQ,EAAE,KAAK,OAAO,KAAK,EAAE,GAAG,UAAU,OAAO,KAAK,QAAQ,GAAG,OAAO,OAAO,KAAK,cAAc,GAAG,OAAO,KAAK,OAAO,MAAM,CAAC;AAC3I,QAAM,MAAM,aAAa,SAAS,cAAc,KAAK,UAAU,CAAC;AAChE,MAAI,QAAQ,IAAI,cAAc,KAAK,EAAE,UAAU,MAAM,MAAM,KAAK,UAAU,OAAO,QAAQ,QAAQ,IAAI,aAAa,cAAc,QAAQ,KAAK,KAAK,EAAE,CAAC;AACrJ,SAAO;AACT;AAEO,MAAM,WAAW;AAAA,EACtB,KAAK,EAAE,aAAa,MAAM;AAC5B;AAEA,MAAM,qBAAqB,EAAE,OAAO;AAAA,EAClC,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oDAAoD;AAC/F,CAAC;AAEM,MAAM,UAA2B;AAAA,EACtC,KAAK;AAAA,EACL,SAAS;AAAA,EACT,SAAS;AAAA,IACP,KAAK;AAAA,MACH,SAAS;AAAA,MACT,aAAa;AAAA,MACb,OAAO;AAAA,MACP,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,qDAAqD,WAAW,YAAY;AAAA,MAC1G;AAAA,IACF;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/core",
|
|
3
|
-
"version": "0.4.2-canary-
|
|
3
|
+
"version": "0.4.2-canary-a8ae8aa761",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -207,7 +207,7 @@
|
|
|
207
207
|
}
|
|
208
208
|
},
|
|
209
209
|
"dependencies": {
|
|
210
|
-
"@open-mercato/shared": "0.4.2-canary-
|
|
210
|
+
"@open-mercato/shared": "0.4.2-canary-a8ae8aa761",
|
|
211
211
|
"@xyflow/react": "^12.6.0",
|
|
212
212
|
"date-fns": "^4.1.0",
|
|
213
213
|
"date-fns-tz": "^3.2.0"
|
|
@@ -12,9 +12,22 @@ function parseCookie(req: Request, name: string): string | null {
|
|
|
12
12
|
return m ? decodeURIComponent(m[1]) : null
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
function sanitizeRedirect(param: string | null, baseUrl: string): string {
|
|
16
|
+
const value = param || '/'
|
|
17
|
+
try {
|
|
18
|
+
const base = new URL(baseUrl)
|
|
19
|
+
const resolved = new URL(value, baseUrl)
|
|
20
|
+
if (resolved.origin === base.origin && resolved.pathname.startsWith('/')) {
|
|
21
|
+
return resolved.pathname + resolved.search + resolved.hash
|
|
22
|
+
}
|
|
23
|
+
} catch {}
|
|
24
|
+
return '/'
|
|
25
|
+
}
|
|
26
|
+
|
|
15
27
|
export async function GET(req: Request) {
|
|
16
28
|
const url = new URL(req.url)
|
|
17
|
-
const
|
|
29
|
+
const baseUrl = process.env.APP_URL || `${url.protocol}//${url.host}`
|
|
30
|
+
const redirectTo = sanitizeRedirect(url.searchParams.get('redirect'), baseUrl)
|
|
18
31
|
const token = parseCookie(req, 'session_token')
|
|
19
32
|
if (!token) return NextResponse.redirect(toAbsoluteUrl(req, '/login?redirect=' + encodeURIComponent(redirectTo)))
|
|
20
33
|
const c = await createRequestContainer()
|