@frequencyads/auth 0.1.0
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/chunk-JIENWB3K.mjs +89 -0
- package/dist/chunk-NS2JRZGO.mjs +38 -0
- package/dist/chunk-OKP757OV.mjs +131 -0
- package/dist/chunk-OUUVIDG6.mjs +63 -0
- package/dist/chunk-P4OKC4U7.mjs +41 -0
- package/dist/chunk-VBLFQXCD.mjs +406 -0
- package/dist/chunk-VQCPN62H.mjs +134 -0
- package/dist/chunk-XJFMS3SM.mjs +21 -0
- package/dist/components/auth-provider.d.mts +24 -0
- package/dist/components/auth-provider.d.ts +24 -0
- package/dist/components/auth-provider.js +107 -0
- package/dist/components/auth-provider.mjs +11 -0
- package/dist/components/login.d.mts +24 -0
- package/dist/components/login.d.ts +24 -0
- package/dist/components/login.js +430 -0
- package/dist/components/login.mjs +9 -0
- package/dist/components/reset-password.d.mts +11 -0
- package/dist/components/reset-password.d.ts +11 -0
- package/dist/components/reset-password.js +283 -0
- package/dist/components/reset-password.mjs +10 -0
- package/dist/components/sign-out-button.d.mts +11 -0
- package/dist/components/sign-out-button.d.ts +11 -0
- package/dist/components/sign-out-button.js +90 -0
- package/dist/components/sign-out-button.mjs +11 -0
- package/dist/components/user-menu.d.mts +5 -0
- package/dist/components/user-menu.d.ts +5 -0
- package/dist/components/user-menu.js +107 -0
- package/dist/components/user-menu.mjs +11 -0
- package/dist/components/verify-code.d.mts +20 -0
- package/dist/components/verify-code.d.ts +20 -0
- package/dist/components/verify-code.js +155 -0
- package/dist/components/verify-code.mjs +9 -0
- package/dist/index.d.mts +44 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.js +1006 -0
- package/dist/index.mjs +159 -0
- package/dist/middleware.d.mts +29 -0
- package/dist/middleware.d.ts +29 -0
- package/dist/middleware.js +114 -0
- package/dist/middleware.mjs +83 -0
- package/dist/proxy.d.mts +9 -0
- package/dist/proxy.d.ts +9 -0
- package/dist/proxy.js +71 -0
- package/dist/proxy.mjs +41 -0
- package/dist/request.d.mts +14 -0
- package/dist/request.d.ts +14 -0
- package/dist/request.js +46 -0
- package/dist/request.mjs +8 -0
- package/package.json +101 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import {
|
|
3
|
+
LoginPage
|
|
4
|
+
} from "./chunk-VBLFQXCD.mjs";
|
|
5
|
+
import {
|
|
6
|
+
UserMenu
|
|
7
|
+
} from "./chunk-OUUVIDG6.mjs";
|
|
8
|
+
import {
|
|
9
|
+
AuthProvider,
|
|
10
|
+
useAuth
|
|
11
|
+
} from "./chunk-JIENWB3K.mjs";
|
|
12
|
+
import {
|
|
13
|
+
SignOutButton,
|
|
14
|
+
getSignOutUrl
|
|
15
|
+
} from "./chunk-P4OKC4U7.mjs";
|
|
16
|
+
import {
|
|
17
|
+
ResetPasswordForm
|
|
18
|
+
} from "./chunk-VQCPN62H.mjs";
|
|
19
|
+
import {
|
|
20
|
+
VerifyCodeForm
|
|
21
|
+
} from "./chunk-OKP757OV.mjs";
|
|
22
|
+
import "./chunk-NS2JRZGO.mjs";
|
|
23
|
+
|
|
24
|
+
// src/lib/proxy.ts
|
|
25
|
+
import { createServerClient } from "@supabase/ssr";
|
|
26
|
+
import { NextResponse } from "next/server";
|
|
27
|
+
import {
|
|
28
|
+
getSupabaseUrl,
|
|
29
|
+
getSupabasePublishableKey,
|
|
30
|
+
getTrustedDomains
|
|
31
|
+
} from "@frequencyads/db/config";
|
|
32
|
+
import { deriveCookieDomain } from "@frequencyads/db/cookies";
|
|
33
|
+
|
|
34
|
+
// src/lib/request.ts
|
|
35
|
+
var isDev = process.env.NODE_ENV === "development";
|
|
36
|
+
function getRequestOrigin(request) {
|
|
37
|
+
var _a;
|
|
38
|
+
if (!isDev) {
|
|
39
|
+
return request.nextUrl.origin;
|
|
40
|
+
}
|
|
41
|
+
const host = (_a = request.headers.get("host")) != null ? _a : request.nextUrl.host;
|
|
42
|
+
return `${request.nextUrl.protocol}//${host}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// src/lib/proxy.ts
|
|
46
|
+
async function updateSession(request) {
|
|
47
|
+
var _a;
|
|
48
|
+
let supabaseResponse = NextResponse.next({ request });
|
|
49
|
+
const hostname = new URL(getRequestOrigin(request)).hostname;
|
|
50
|
+
const cookieDomain = deriveCookieDomain(hostname, getTrustedDomains());
|
|
51
|
+
const cookieOptions = cookieDomain ? { domain: cookieDomain } : void 0;
|
|
52
|
+
const supabase = createServerClient(getSupabaseUrl(), getSupabasePublishableKey(), {
|
|
53
|
+
cookieOptions,
|
|
54
|
+
cookies: {
|
|
55
|
+
getAll() {
|
|
56
|
+
return request.cookies.getAll();
|
|
57
|
+
},
|
|
58
|
+
setAll(cookiesToSet) {
|
|
59
|
+
cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value));
|
|
60
|
+
supabaseResponse = NextResponse.next({ request });
|
|
61
|
+
cookiesToSet.forEach(
|
|
62
|
+
({ name, value, options }) => supabaseResponse.cookies.set(name, value, options)
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
const { data } = await supabase.auth.getClaims();
|
|
68
|
+
const claims = (_a = data == null ? void 0 : data.claims) != null ? _a : null;
|
|
69
|
+
return { supabaseResponse, claims };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/middleware.ts
|
|
73
|
+
import { createServerClient as createServerClient2 } from "@supabase/ssr";
|
|
74
|
+
import { NextResponse as NextResponse2 } from "next/server";
|
|
75
|
+
import {
|
|
76
|
+
getSupabaseUrl as getSupabaseUrl2,
|
|
77
|
+
getSupabasePublishableKey as getSupabasePublishableKey2,
|
|
78
|
+
getTrustedDomains as getTrustedDomains2
|
|
79
|
+
} from "@frequencyads/db/config";
|
|
80
|
+
import { deriveCookieDomain as deriveCookieDomain2 } from "@frequencyads/db/cookies";
|
|
81
|
+
function getAccountsUrl() {
|
|
82
|
+
const url = process.env.NEXT_PUBLIC_ACCOUNTS_URL;
|
|
83
|
+
if (!url) throw new Error("Missing required env var: NEXT_PUBLIC_ACCOUNTS_URL");
|
|
84
|
+
return url;
|
|
85
|
+
}
|
|
86
|
+
async function getSessionAndClaims(request) {
|
|
87
|
+
var _a;
|
|
88
|
+
let supabaseResponse = NextResponse2.next({ request });
|
|
89
|
+
const hostname = new URL(getRequestOrigin(request)).hostname;
|
|
90
|
+
const cookieDomain = deriveCookieDomain2(hostname, getTrustedDomains2());
|
|
91
|
+
const cookieOptions = cookieDomain ? { domain: cookieDomain } : void 0;
|
|
92
|
+
const supabase = createServerClient2(getSupabaseUrl2(), getSupabasePublishableKey2(), {
|
|
93
|
+
cookieOptions,
|
|
94
|
+
cookies: {
|
|
95
|
+
getAll() {
|
|
96
|
+
return request.cookies.getAll();
|
|
97
|
+
},
|
|
98
|
+
setAll(cookiesToSet) {
|
|
99
|
+
cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value));
|
|
100
|
+
supabaseResponse = NextResponse2.next({ request });
|
|
101
|
+
cookiesToSet.forEach(
|
|
102
|
+
({ name, value, options }) => supabaseResponse.cookies.set(name, value, options)
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
const { data } = await supabase.auth.getClaims();
|
|
108
|
+
const claims = (_a = data == null ? void 0 : data.claims) != null ? _a : null;
|
|
109
|
+
return { supabase, supabaseResponse, claims };
|
|
110
|
+
}
|
|
111
|
+
async function isOrgMember(supabase, userId) {
|
|
112
|
+
const { data } = await supabase.from("perm_organization_member").select("id").eq("user_id", userId).limit(1).maybeSingle();
|
|
113
|
+
return data !== null;
|
|
114
|
+
}
|
|
115
|
+
async function isEmployee(supabase, userId) {
|
|
116
|
+
const { data } = await supabase.from("perm_user_global_role").select("role").eq("user_id", userId).maybeSingle();
|
|
117
|
+
return (data == null ? void 0 : data.role) === "EMPLOYEE" || (data == null ? void 0 : data.role) === "ADMIN";
|
|
118
|
+
}
|
|
119
|
+
function createAuthMiddleware({ access }) {
|
|
120
|
+
return async function middleware(request) {
|
|
121
|
+
const { supabase, supabaseResponse, claims } = await getSessionAndClaims(request);
|
|
122
|
+
const accountsUrl = getAccountsUrl();
|
|
123
|
+
const currentUrl = request.nextUrl.href;
|
|
124
|
+
if (!claims) {
|
|
125
|
+
const loginUrl = `${accountsUrl}/login?next=${encodeURIComponent(currentUrl)}`;
|
|
126
|
+
return NextResponse2.redirect(loginUrl);
|
|
127
|
+
}
|
|
128
|
+
const userId = claims.sub;
|
|
129
|
+
let authorized = false;
|
|
130
|
+
if (access === "org-member") {
|
|
131
|
+
authorized = await isOrgMember(supabase, userId);
|
|
132
|
+
} else if (access === "employee") {
|
|
133
|
+
authorized = await isEmployee(supabase, userId);
|
|
134
|
+
}
|
|
135
|
+
if (!authorized) {
|
|
136
|
+
const deniedUrl = `${accountsUrl}?error=access_denied&from=${encodeURIComponent(currentUrl)}`;
|
|
137
|
+
return NextResponse2.redirect(deniedUrl);
|
|
138
|
+
}
|
|
139
|
+
return supabaseResponse;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
var defaultMatcher = {
|
|
143
|
+
matcher: [
|
|
144
|
+
"/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico)$).*)"
|
|
145
|
+
]
|
|
146
|
+
};
|
|
147
|
+
export {
|
|
148
|
+
AuthProvider,
|
|
149
|
+
LoginPage,
|
|
150
|
+
ResetPasswordForm,
|
|
151
|
+
SignOutButton,
|
|
152
|
+
UserMenu,
|
|
153
|
+
VerifyCodeForm,
|
|
154
|
+
createAuthMiddleware,
|
|
155
|
+
defaultMatcher,
|
|
156
|
+
getSignOutUrl,
|
|
157
|
+
updateSession,
|
|
158
|
+
useAuth
|
|
159
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
|
|
3
|
+
type AccessLevel = 'org-member' | 'employee';
|
|
4
|
+
interface AuthMiddlewareOptions {
|
|
5
|
+
/** Required access level for this app. */
|
|
6
|
+
access: AccessLevel;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Create a Next.js middleware that gates access based on org membership or employee role.
|
|
10
|
+
*
|
|
11
|
+
* - Unauthenticated users are redirected to account.frequency.media/login
|
|
12
|
+
* - Authenticated users without the required access level are redirected to
|
|
13
|
+
* account.frequency.media with an access_denied error
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // middleware.ts (private app — org members only)
|
|
17
|
+
* export const middleware = createAuthMiddleware({ access: 'org-member' });
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // middleware.ts (internal app — employees only)
|
|
21
|
+
* export const middleware = createAuthMiddleware({ access: 'employee' });
|
|
22
|
+
*/
|
|
23
|
+
declare function createAuthMiddleware({ access }: AuthMiddlewareOptions): (request: NextRequest) => Promise<NextResponse<unknown>>;
|
|
24
|
+
/** Default matcher config for use in consuming apps. */
|
|
25
|
+
declare const defaultMatcher: {
|
|
26
|
+
matcher: string[];
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export { createAuthMiddleware, defaultMatcher };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
2
|
+
|
|
3
|
+
type AccessLevel = 'org-member' | 'employee';
|
|
4
|
+
interface AuthMiddlewareOptions {
|
|
5
|
+
/** Required access level for this app. */
|
|
6
|
+
access: AccessLevel;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Create a Next.js middleware that gates access based on org membership or employee role.
|
|
10
|
+
*
|
|
11
|
+
* - Unauthenticated users are redirected to account.frequency.media/login
|
|
12
|
+
* - Authenticated users without the required access level are redirected to
|
|
13
|
+
* account.frequency.media with an access_denied error
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* // middleware.ts (private app — org members only)
|
|
17
|
+
* export const middleware = createAuthMiddleware({ access: 'org-member' });
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // middleware.ts (internal app — employees only)
|
|
21
|
+
* export const middleware = createAuthMiddleware({ access: 'employee' });
|
|
22
|
+
*/
|
|
23
|
+
declare function createAuthMiddleware({ access }: AuthMiddlewareOptions): (request: NextRequest) => Promise<NextResponse<unknown>>;
|
|
24
|
+
/** Default matcher config for use in consuming apps. */
|
|
25
|
+
declare const defaultMatcher: {
|
|
26
|
+
matcher: string[];
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export { createAuthMiddleware, defaultMatcher };
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/middleware.ts
|
|
21
|
+
var middleware_exports = {};
|
|
22
|
+
__export(middleware_exports, {
|
|
23
|
+
createAuthMiddleware: () => createAuthMiddleware,
|
|
24
|
+
defaultMatcher: () => defaultMatcher
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(middleware_exports);
|
|
27
|
+
var import_ssr = require("@supabase/ssr");
|
|
28
|
+
var import_server = require("next/server");
|
|
29
|
+
var import_config = require("@frequencyads/db/config");
|
|
30
|
+
var import_cookies = require("@frequencyads/db/cookies");
|
|
31
|
+
|
|
32
|
+
// src/lib/request.ts
|
|
33
|
+
var isDev = process.env.NODE_ENV === "development";
|
|
34
|
+
function getRequestOrigin(request) {
|
|
35
|
+
var _a;
|
|
36
|
+
if (!isDev) {
|
|
37
|
+
return request.nextUrl.origin;
|
|
38
|
+
}
|
|
39
|
+
const host = (_a = request.headers.get("host")) != null ? _a : request.nextUrl.host;
|
|
40
|
+
return `${request.nextUrl.protocol}//${host}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// src/middleware.ts
|
|
44
|
+
function getAccountsUrl() {
|
|
45
|
+
const url = process.env.NEXT_PUBLIC_ACCOUNTS_URL;
|
|
46
|
+
if (!url) throw new Error("Missing required env var: NEXT_PUBLIC_ACCOUNTS_URL");
|
|
47
|
+
return url;
|
|
48
|
+
}
|
|
49
|
+
async function getSessionAndClaims(request) {
|
|
50
|
+
var _a;
|
|
51
|
+
let supabaseResponse = import_server.NextResponse.next({ request });
|
|
52
|
+
const hostname = new URL(getRequestOrigin(request)).hostname;
|
|
53
|
+
const cookieDomain = (0, import_cookies.deriveCookieDomain)(hostname, (0, import_config.getTrustedDomains)());
|
|
54
|
+
const cookieOptions = cookieDomain ? { domain: cookieDomain } : void 0;
|
|
55
|
+
const supabase = (0, import_ssr.createServerClient)((0, import_config.getSupabaseUrl)(), (0, import_config.getSupabasePublishableKey)(), {
|
|
56
|
+
cookieOptions,
|
|
57
|
+
cookies: {
|
|
58
|
+
getAll() {
|
|
59
|
+
return request.cookies.getAll();
|
|
60
|
+
},
|
|
61
|
+
setAll(cookiesToSet) {
|
|
62
|
+
cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value));
|
|
63
|
+
supabaseResponse = import_server.NextResponse.next({ request });
|
|
64
|
+
cookiesToSet.forEach(
|
|
65
|
+
({ name, value, options }) => supabaseResponse.cookies.set(name, value, options)
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
const { data } = await supabase.auth.getClaims();
|
|
71
|
+
const claims = (_a = data == null ? void 0 : data.claims) != null ? _a : null;
|
|
72
|
+
return { supabase, supabaseResponse, claims };
|
|
73
|
+
}
|
|
74
|
+
async function isOrgMember(supabase, userId) {
|
|
75
|
+
const { data } = await supabase.from("perm_organization_member").select("id").eq("user_id", userId).limit(1).maybeSingle();
|
|
76
|
+
return data !== null;
|
|
77
|
+
}
|
|
78
|
+
async function isEmployee(supabase, userId) {
|
|
79
|
+
const { data } = await supabase.from("perm_user_global_role").select("role").eq("user_id", userId).maybeSingle();
|
|
80
|
+
return (data == null ? void 0 : data.role) === "EMPLOYEE" || (data == null ? void 0 : data.role) === "ADMIN";
|
|
81
|
+
}
|
|
82
|
+
function createAuthMiddleware({ access }) {
|
|
83
|
+
return async function middleware(request) {
|
|
84
|
+
const { supabase, supabaseResponse, claims } = await getSessionAndClaims(request);
|
|
85
|
+
const accountsUrl = getAccountsUrl();
|
|
86
|
+
const currentUrl = request.nextUrl.href;
|
|
87
|
+
if (!claims) {
|
|
88
|
+
const loginUrl = `${accountsUrl}/login?next=${encodeURIComponent(currentUrl)}`;
|
|
89
|
+
return import_server.NextResponse.redirect(loginUrl);
|
|
90
|
+
}
|
|
91
|
+
const userId = claims.sub;
|
|
92
|
+
let authorized = false;
|
|
93
|
+
if (access === "org-member") {
|
|
94
|
+
authorized = await isOrgMember(supabase, userId);
|
|
95
|
+
} else if (access === "employee") {
|
|
96
|
+
authorized = await isEmployee(supabase, userId);
|
|
97
|
+
}
|
|
98
|
+
if (!authorized) {
|
|
99
|
+
const deniedUrl = `${accountsUrl}?error=access_denied&from=${encodeURIComponent(currentUrl)}`;
|
|
100
|
+
return import_server.NextResponse.redirect(deniedUrl);
|
|
101
|
+
}
|
|
102
|
+
return supabaseResponse;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
var defaultMatcher = {
|
|
106
|
+
matcher: [
|
|
107
|
+
"/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico)$).*)"
|
|
108
|
+
]
|
|
109
|
+
};
|
|
110
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
111
|
+
0 && (module.exports = {
|
|
112
|
+
createAuthMiddleware,
|
|
113
|
+
defaultMatcher
|
|
114
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getRequestOrigin
|
|
3
|
+
} from "./chunk-XJFMS3SM.mjs";
|
|
4
|
+
|
|
5
|
+
// src/middleware.ts
|
|
6
|
+
import { createServerClient } from "@supabase/ssr";
|
|
7
|
+
import { NextResponse } from "next/server";
|
|
8
|
+
import {
|
|
9
|
+
getSupabaseUrl,
|
|
10
|
+
getSupabasePublishableKey,
|
|
11
|
+
getTrustedDomains
|
|
12
|
+
} from "@frequencyads/db/config";
|
|
13
|
+
import { deriveCookieDomain } from "@frequencyads/db/cookies";
|
|
14
|
+
function getAccountsUrl() {
|
|
15
|
+
const url = process.env.NEXT_PUBLIC_ACCOUNTS_URL;
|
|
16
|
+
if (!url) throw new Error("Missing required env var: NEXT_PUBLIC_ACCOUNTS_URL");
|
|
17
|
+
return url;
|
|
18
|
+
}
|
|
19
|
+
async function getSessionAndClaims(request) {
|
|
20
|
+
var _a;
|
|
21
|
+
let supabaseResponse = NextResponse.next({ request });
|
|
22
|
+
const hostname = new URL(getRequestOrigin(request)).hostname;
|
|
23
|
+
const cookieDomain = deriveCookieDomain(hostname, getTrustedDomains());
|
|
24
|
+
const cookieOptions = cookieDomain ? { domain: cookieDomain } : void 0;
|
|
25
|
+
const supabase = createServerClient(getSupabaseUrl(), getSupabasePublishableKey(), {
|
|
26
|
+
cookieOptions,
|
|
27
|
+
cookies: {
|
|
28
|
+
getAll() {
|
|
29
|
+
return request.cookies.getAll();
|
|
30
|
+
},
|
|
31
|
+
setAll(cookiesToSet) {
|
|
32
|
+
cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value));
|
|
33
|
+
supabaseResponse = NextResponse.next({ request });
|
|
34
|
+
cookiesToSet.forEach(
|
|
35
|
+
({ name, value, options }) => supabaseResponse.cookies.set(name, value, options)
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const { data } = await supabase.auth.getClaims();
|
|
41
|
+
const claims = (_a = data == null ? void 0 : data.claims) != null ? _a : null;
|
|
42
|
+
return { supabase, supabaseResponse, claims };
|
|
43
|
+
}
|
|
44
|
+
async function isOrgMember(supabase, userId) {
|
|
45
|
+
const { data } = await supabase.from("perm_organization_member").select("id").eq("user_id", userId).limit(1).maybeSingle();
|
|
46
|
+
return data !== null;
|
|
47
|
+
}
|
|
48
|
+
async function isEmployee(supabase, userId) {
|
|
49
|
+
const { data } = await supabase.from("perm_user_global_role").select("role").eq("user_id", userId).maybeSingle();
|
|
50
|
+
return (data == null ? void 0 : data.role) === "EMPLOYEE" || (data == null ? void 0 : data.role) === "ADMIN";
|
|
51
|
+
}
|
|
52
|
+
function createAuthMiddleware({ access }) {
|
|
53
|
+
return async function middleware(request) {
|
|
54
|
+
const { supabase, supabaseResponse, claims } = await getSessionAndClaims(request);
|
|
55
|
+
const accountsUrl = getAccountsUrl();
|
|
56
|
+
const currentUrl = request.nextUrl.href;
|
|
57
|
+
if (!claims) {
|
|
58
|
+
const loginUrl = `${accountsUrl}/login?next=${encodeURIComponent(currentUrl)}`;
|
|
59
|
+
return NextResponse.redirect(loginUrl);
|
|
60
|
+
}
|
|
61
|
+
const userId = claims.sub;
|
|
62
|
+
let authorized = false;
|
|
63
|
+
if (access === "org-member") {
|
|
64
|
+
authorized = await isOrgMember(supabase, userId);
|
|
65
|
+
} else if (access === "employee") {
|
|
66
|
+
authorized = await isEmployee(supabase, userId);
|
|
67
|
+
}
|
|
68
|
+
if (!authorized) {
|
|
69
|
+
const deniedUrl = `${accountsUrl}?error=access_denied&from=${encodeURIComponent(currentUrl)}`;
|
|
70
|
+
return NextResponse.redirect(deniedUrl);
|
|
71
|
+
}
|
|
72
|
+
return supabaseResponse;
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
var defaultMatcher = {
|
|
76
|
+
matcher: [
|
|
77
|
+
"/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico)$).*)"
|
|
78
|
+
]
|
|
79
|
+
};
|
|
80
|
+
export {
|
|
81
|
+
createAuthMiddleware,
|
|
82
|
+
defaultMatcher
|
|
83
|
+
};
|
package/dist/proxy.d.mts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as _supabase_supabase_js from '@supabase/supabase-js';
|
|
2
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
3
|
+
|
|
4
|
+
declare function updateSession(request: NextRequest): Promise<{
|
|
5
|
+
supabaseResponse: NextResponse<unknown>;
|
|
6
|
+
claims: _supabase_supabase_js.JwtPayload | null;
|
|
7
|
+
}>;
|
|
8
|
+
|
|
9
|
+
export { updateSession };
|
package/dist/proxy.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as _supabase_supabase_js from '@supabase/supabase-js';
|
|
2
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
3
|
+
|
|
4
|
+
declare function updateSession(request: NextRequest): Promise<{
|
|
5
|
+
supabaseResponse: NextResponse<unknown>;
|
|
6
|
+
claims: _supabase_supabase_js.JwtPayload | null;
|
|
7
|
+
}>;
|
|
8
|
+
|
|
9
|
+
export { updateSession };
|
package/dist/proxy.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/lib/proxy.ts
|
|
21
|
+
var proxy_exports = {};
|
|
22
|
+
__export(proxy_exports, {
|
|
23
|
+
updateSession: () => updateSession
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(proxy_exports);
|
|
26
|
+
var import_ssr = require("@supabase/ssr");
|
|
27
|
+
var import_server = require("next/server");
|
|
28
|
+
var import_config = require("@frequencyads/db/config");
|
|
29
|
+
var import_cookies = require("@frequencyads/db/cookies");
|
|
30
|
+
|
|
31
|
+
// src/lib/request.ts
|
|
32
|
+
var isDev = process.env.NODE_ENV === "development";
|
|
33
|
+
function getRequestOrigin(request) {
|
|
34
|
+
var _a;
|
|
35
|
+
if (!isDev) {
|
|
36
|
+
return request.nextUrl.origin;
|
|
37
|
+
}
|
|
38
|
+
const host = (_a = request.headers.get("host")) != null ? _a : request.nextUrl.host;
|
|
39
|
+
return `${request.nextUrl.protocol}//${host}`;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// src/lib/proxy.ts
|
|
43
|
+
async function updateSession(request) {
|
|
44
|
+
var _a;
|
|
45
|
+
let supabaseResponse = import_server.NextResponse.next({ request });
|
|
46
|
+
const hostname = new URL(getRequestOrigin(request)).hostname;
|
|
47
|
+
const cookieDomain = (0, import_cookies.deriveCookieDomain)(hostname, (0, import_config.getTrustedDomains)());
|
|
48
|
+
const cookieOptions = cookieDomain ? { domain: cookieDomain } : void 0;
|
|
49
|
+
const supabase = (0, import_ssr.createServerClient)((0, import_config.getSupabaseUrl)(), (0, import_config.getSupabasePublishableKey)(), {
|
|
50
|
+
cookieOptions,
|
|
51
|
+
cookies: {
|
|
52
|
+
getAll() {
|
|
53
|
+
return request.cookies.getAll();
|
|
54
|
+
},
|
|
55
|
+
setAll(cookiesToSet) {
|
|
56
|
+
cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value));
|
|
57
|
+
supabaseResponse = import_server.NextResponse.next({ request });
|
|
58
|
+
cookiesToSet.forEach(
|
|
59
|
+
({ name, value, options }) => supabaseResponse.cookies.set(name, value, options)
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
const { data } = await supabase.auth.getClaims();
|
|
65
|
+
const claims = (_a = data == null ? void 0 : data.claims) != null ? _a : null;
|
|
66
|
+
return { supabaseResponse, claims };
|
|
67
|
+
}
|
|
68
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
69
|
+
0 && (module.exports = {
|
|
70
|
+
updateSession
|
|
71
|
+
});
|
package/dist/proxy.mjs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getRequestOrigin
|
|
3
|
+
} from "./chunk-XJFMS3SM.mjs";
|
|
4
|
+
|
|
5
|
+
// src/lib/proxy.ts
|
|
6
|
+
import { createServerClient } from "@supabase/ssr";
|
|
7
|
+
import { NextResponse } from "next/server";
|
|
8
|
+
import {
|
|
9
|
+
getSupabaseUrl,
|
|
10
|
+
getSupabasePublishableKey,
|
|
11
|
+
getTrustedDomains
|
|
12
|
+
} from "@frequencyads/db/config";
|
|
13
|
+
import { deriveCookieDomain } from "@frequencyads/db/cookies";
|
|
14
|
+
async function updateSession(request) {
|
|
15
|
+
var _a;
|
|
16
|
+
let supabaseResponse = NextResponse.next({ request });
|
|
17
|
+
const hostname = new URL(getRequestOrigin(request)).hostname;
|
|
18
|
+
const cookieDomain = deriveCookieDomain(hostname, getTrustedDomains());
|
|
19
|
+
const cookieOptions = cookieDomain ? { domain: cookieDomain } : void 0;
|
|
20
|
+
const supabase = createServerClient(getSupabaseUrl(), getSupabasePublishableKey(), {
|
|
21
|
+
cookieOptions,
|
|
22
|
+
cookies: {
|
|
23
|
+
getAll() {
|
|
24
|
+
return request.cookies.getAll();
|
|
25
|
+
},
|
|
26
|
+
setAll(cookiesToSet) {
|
|
27
|
+
cookiesToSet.forEach(({ name, value }) => request.cookies.set(name, value));
|
|
28
|
+
supabaseResponse = NextResponse.next({ request });
|
|
29
|
+
cookiesToSet.forEach(
|
|
30
|
+
({ name, value, options }) => supabaseResponse.cookies.set(name, value, options)
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
const { data } = await supabase.auth.getClaims();
|
|
36
|
+
const claims = (_a = data == null ? void 0 : data.claims) != null ? _a : null;
|
|
37
|
+
return { supabaseResponse, claims };
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
updateSession
|
|
41
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { NextRequest } from 'next/server';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Derive the public origin (protocol + host, no path) from a request.
|
|
5
|
+
*
|
|
6
|
+
* In production/staging, `request.nextUrl.origin` is correct (Vercel sets it).
|
|
7
|
+
* In local dev with nip.io domains, Next.js mangles the hostname so
|
|
8
|
+
* we read from the Host header instead.
|
|
9
|
+
*/
|
|
10
|
+
declare function getRequestOrigin(request: NextRequest): string;
|
|
11
|
+
/** Build the public-facing full URL for the current request. */
|
|
12
|
+
declare function getRequestUrl(request: NextRequest): string;
|
|
13
|
+
|
|
14
|
+
export { getRequestOrigin, getRequestUrl };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { NextRequest } from 'next/server';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Derive the public origin (protocol + host, no path) from a request.
|
|
5
|
+
*
|
|
6
|
+
* In production/staging, `request.nextUrl.origin` is correct (Vercel sets it).
|
|
7
|
+
* In local dev with nip.io domains, Next.js mangles the hostname so
|
|
8
|
+
* we read from the Host header instead.
|
|
9
|
+
*/
|
|
10
|
+
declare function getRequestOrigin(request: NextRequest): string;
|
|
11
|
+
/** Build the public-facing full URL for the current request. */
|
|
12
|
+
declare function getRequestUrl(request: NextRequest): string;
|
|
13
|
+
|
|
14
|
+
export { getRequestOrigin, getRequestUrl };
|
package/dist/request.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/lib/request.ts
|
|
21
|
+
var request_exports = {};
|
|
22
|
+
__export(request_exports, {
|
|
23
|
+
getRequestOrigin: () => getRequestOrigin,
|
|
24
|
+
getRequestUrl: () => getRequestUrl
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(request_exports);
|
|
27
|
+
var isDev = process.env.NODE_ENV === "development";
|
|
28
|
+
function getRequestOrigin(request) {
|
|
29
|
+
var _a;
|
|
30
|
+
if (!isDev) {
|
|
31
|
+
return request.nextUrl.origin;
|
|
32
|
+
}
|
|
33
|
+
const host = (_a = request.headers.get("host")) != null ? _a : request.nextUrl.host;
|
|
34
|
+
return `${request.nextUrl.protocol}//${host}`;
|
|
35
|
+
}
|
|
36
|
+
function getRequestUrl(request) {
|
|
37
|
+
if (!isDev) {
|
|
38
|
+
return request.url;
|
|
39
|
+
}
|
|
40
|
+
return `${getRequestOrigin(request)}${request.nextUrl.pathname}${request.nextUrl.search}`;
|
|
41
|
+
}
|
|
42
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
43
|
+
0 && (module.exports = {
|
|
44
|
+
getRequestOrigin,
|
|
45
|
+
getRequestUrl
|
|
46
|
+
});
|