@lifelens/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/LICENSE +21 -0
- package/dist/bridge.d.ts +4 -0
- package/dist/bridge.d.ts.map +1 -0
- package/dist/bridge.js +54 -0
- package/dist/bridge.js.map +1 -0
- package/dist/callback.d.ts +10 -0
- package/dist/callback.d.ts.map +1 -0
- package/dist/callback.js +83 -0
- package/dist/callback.js.map +1 -0
- package/dist/client.d.ts +3 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +9 -0
- package/dist/client.js.map +1 -0
- package/dist/context.d.ts +31 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +113 -0
- package/dist/context.js.map +1 -0
- package/dist/guard.d.ts +10 -0
- package/dist/guard.d.ts.map +1 -0
- package/dist/guard.js +60 -0
- package/dist/guard.js.map +1 -0
- package/dist/server.d.ts +11 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +40 -0
- package/dist/server.js.map +1 -0
- package/package.json +81 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 LifeLens
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/bridge.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAgB/C,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,IACrB,SAAS,WAAW,KAAG,OAAO,CAAC,YAAY,CAAC,CAyDxE"}
|
package/dist/bridge.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createServerClient } from "@supabase/ssr";
|
|
2
|
+
import { cookies } from "next/headers";
|
|
3
|
+
import { NextResponse } from "next/server";
|
|
4
|
+
const COOKIE_OPTIONS = process.env.COOKIE_DOMAIN
|
|
5
|
+
? { domain: process.env.COOKIE_DOMAIN }
|
|
6
|
+
: undefined;
|
|
7
|
+
function getSafeRedirectPath(value) {
|
|
8
|
+
return value && value.startsWith("/") && !value.startsWith("//")
|
|
9
|
+
? value
|
|
10
|
+
: "/";
|
|
11
|
+
}
|
|
12
|
+
function getStringValue(value) {
|
|
13
|
+
return typeof value === "string" ? value : null;
|
|
14
|
+
}
|
|
15
|
+
export function createBridgeHandler(hubUrl) {
|
|
16
|
+
return async function POST(request) {
|
|
17
|
+
const requestUrl = new URL(request.url);
|
|
18
|
+
const formData = await request.formData();
|
|
19
|
+
const accessToken = getStringValue(formData.get("access_token"));
|
|
20
|
+
const refreshToken = getStringValue(formData.get("refresh_token"));
|
|
21
|
+
const redirectPath = getSafeRedirectPath(getStringValue(formData.get("redirect")));
|
|
22
|
+
if (!accessToken || !refreshToken) {
|
|
23
|
+
const loginUrl = new URL(`${hubUrl}/login`);
|
|
24
|
+
loginUrl.searchParams.set("redirect", new URL(redirectPath, requestUrl.origin).toString());
|
|
25
|
+
return NextResponse.redirect(loginUrl, 303);
|
|
26
|
+
}
|
|
27
|
+
const cookieStore = await cookies();
|
|
28
|
+
const response = NextResponse.redirect(new URL(redirectPath, requestUrl.origin), 303);
|
|
29
|
+
const supabase = createServerClient(process.env.NEXT_PUBLIC_SUPABASE_URL, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, {
|
|
30
|
+
cookieOptions: COOKIE_OPTIONS,
|
|
31
|
+
cookies: {
|
|
32
|
+
getAll() {
|
|
33
|
+
return cookieStore.getAll();
|
|
34
|
+
},
|
|
35
|
+
setAll(cookiesToSet) {
|
|
36
|
+
cookiesToSet.forEach(({ name, value, options }) => {
|
|
37
|
+
response.cookies.set(name, value, options);
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
const { error } = await supabase.auth.setSession({
|
|
43
|
+
access_token: accessToken,
|
|
44
|
+
refresh_token: refreshToken,
|
|
45
|
+
});
|
|
46
|
+
if (error) {
|
|
47
|
+
const loginUrl = new URL(`${hubUrl}/login`);
|
|
48
|
+
loginUrl.searchParams.set("redirect", new URL(redirectPath, requestUrl.origin).toString());
|
|
49
|
+
return NextResponse.redirect(loginUrl, 303);
|
|
50
|
+
}
|
|
51
|
+
return response;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import type { NextRequest } from "next/server";
|
|
3
|
+
export interface CallbackHandlerOptions {
|
|
4
|
+
isHub?: boolean;
|
|
5
|
+
hubUrl?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
logging?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function createCallbackHandler({ isHub, hubUrl, name, logging, }?: CallbackHandlerOptions): (request: NextRequest) => Promise<NextResponse>;
|
|
10
|
+
//# sourceMappingURL=callback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback.d.ts","sourceRoot":"","sources":["../src/callback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAoB/C,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,qBAAqB,CAAC,EACpC,KAAa,EACb,MAAM,EACN,IAAa,EACb,OAAe,GAChB,GAAE,sBAA2B,IAGF,SAAS,WAAW,KAAG,OAAO,CAAC,YAAY,CAAC,CA8EvE"}
|
package/dist/callback.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import { createServerClient } from "@supabase/ssr";
|
|
3
|
+
import { cookies } from "next/headers";
|
|
4
|
+
const COOKIE_OPTIONS = process.env.COOKIE_DOMAIN
|
|
5
|
+
? { domain: process.env.COOKIE_DOMAIN }
|
|
6
|
+
: undefined;
|
|
7
|
+
function getSafeRedirectPath(value) {
|
|
8
|
+
return value && value.startsWith("/") && !value.startsWith("//")
|
|
9
|
+
? value
|
|
10
|
+
: "/";
|
|
11
|
+
}
|
|
12
|
+
function createLogger(name) {
|
|
13
|
+
return {
|
|
14
|
+
log: (...args) => console.log(`[${name}]`, ...args),
|
|
15
|
+
error: (...args) => console.error(`[${name}]`, ...args),
|
|
16
|
+
warn: (...args) => console.warn(`[${name}]`, ...args),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export function createCallbackHandler({ isHub = false, hubUrl, name = "auth", logging = false, } = {}) {
|
|
20
|
+
const log = logging ? createLogger(name) : null;
|
|
21
|
+
return async function GET(request) {
|
|
22
|
+
const requestUrl = new URL(request.url);
|
|
23
|
+
const code = requestUrl.searchParams.get("code");
|
|
24
|
+
const origin = requestUrl.origin;
|
|
25
|
+
if (log)
|
|
26
|
+
log.log("Auth callback started", { hasCode: !!code, origin });
|
|
27
|
+
if (code) {
|
|
28
|
+
const cookieStore = await cookies();
|
|
29
|
+
const next = getSafeRedirectPath(requestUrl.searchParams.get("next") ?? "/");
|
|
30
|
+
const redirectPath = isHub && next === "/auth/callback" ? "/" : next;
|
|
31
|
+
const response = NextResponse.redirect(`${origin}${redirectPath}`);
|
|
32
|
+
const supabase = createServerClient(process.env.NEXT_PUBLIC_SUPABASE_URL, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, {
|
|
33
|
+
cookieOptions: COOKIE_OPTIONS,
|
|
34
|
+
cookies: {
|
|
35
|
+
getAll() {
|
|
36
|
+
return cookieStore.getAll();
|
|
37
|
+
},
|
|
38
|
+
setAll(cookiesToSet) {
|
|
39
|
+
if (log) {
|
|
40
|
+
log.log("Setting cookies:", cookiesToSet.map((c) => ({
|
|
41
|
+
name: c.name,
|
|
42
|
+
valueLength: c.value?.length,
|
|
43
|
+
})));
|
|
44
|
+
}
|
|
45
|
+
cookiesToSet.forEach(({ name, value, options }) => {
|
|
46
|
+
response.cookies.set(name, value, options);
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
if (log)
|
|
52
|
+
log.log("Exchanging code for session...");
|
|
53
|
+
const { data, error } = await supabase.auth.exchangeCodeForSession(code);
|
|
54
|
+
if (error) {
|
|
55
|
+
if (log)
|
|
56
|
+
log.error("Auth callback error:", error);
|
|
57
|
+
if (isHub) {
|
|
58
|
+
return NextResponse.redirect(`${origin}/login?error=${error.message}`);
|
|
59
|
+
}
|
|
60
|
+
const loginUrl = new URL(`${hubUrl}/login`);
|
|
61
|
+
loginUrl.searchParams.set("redirect", `${origin}${redirectPath}`);
|
|
62
|
+
return NextResponse.redirect(loginUrl);
|
|
63
|
+
}
|
|
64
|
+
if (log) {
|
|
65
|
+
log.log("Auth session established", {
|
|
66
|
+
userId: data?.user?.id,
|
|
67
|
+
email: data?.user?.email,
|
|
68
|
+
hasSession: !!data?.session,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return response;
|
|
72
|
+
}
|
|
73
|
+
if (log)
|
|
74
|
+
log.log("No code provided");
|
|
75
|
+
if (isHub) {
|
|
76
|
+
return NextResponse.redirect(`${origin}/login`);
|
|
77
|
+
}
|
|
78
|
+
const loginUrl = new URL(`${hubUrl}/login`);
|
|
79
|
+
loginUrl.searchParams.set("redirect", origin);
|
|
80
|
+
return NextResponse.redirect(loginUrl);
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=callback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"callback.js","sourceRoot":"","sources":["../src/callback.ts"],"names":[],"mappings":"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"}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAI5D,wBAAgB,wBAAwB,IAAI,cAAc,CAQzD"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createBrowserClient } from "@supabase/ssr";
|
|
2
|
+
let supabaseClient = null;
|
|
3
|
+
export function getSupabaseBrowserClient() {
|
|
4
|
+
if (!supabaseClient) {
|
|
5
|
+
supabaseClient = createBrowserClient(process.env.NEXT_PUBLIC_SUPABASE_URL, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY);
|
|
6
|
+
}
|
|
7
|
+
return supabaseClient;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAGpD,IAAI,cAAc,GAA0B,IAAI,CAAC;AAEjD,MAAM,UAAU,wBAAwB;IACtC,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,mBAAmB,CAClC,OAAO,CAAC,GAAG,CAAC,wBAAyB,EACrC,OAAO,CAAC,GAAG,CAAC,6BAA8B,CAC3C,CAAC;IACJ,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { User } from "@supabase/supabase-js";
|
|
3
|
+
export interface AuthContextValue {
|
|
4
|
+
user: User | null;
|
|
5
|
+
loading: boolean;
|
|
6
|
+
signInWithGoogle: (options?: {
|
|
7
|
+
redirectTo?: string;
|
|
8
|
+
}) => Promise<{
|
|
9
|
+
provider: string;
|
|
10
|
+
url: string | null;
|
|
11
|
+
} | null>;
|
|
12
|
+
signInWithEmail: (email: string, password: string) => Promise<{
|
|
13
|
+
user: User;
|
|
14
|
+
session: unknown;
|
|
15
|
+
} | null>;
|
|
16
|
+
signUpWithEmail: (email: string, password: string, fullName: string, options?: {
|
|
17
|
+
emailRedirectTo?: string;
|
|
18
|
+
}) => Promise<{
|
|
19
|
+
user: User | null;
|
|
20
|
+
session: unknown;
|
|
21
|
+
} | null>;
|
|
22
|
+
resetPassword: (email: string) => Promise<void>;
|
|
23
|
+
signOut: () => Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
interface AuthProviderProps {
|
|
26
|
+
children: ReactNode;
|
|
27
|
+
}
|
|
28
|
+
export declare const useAuth: () => AuthContextValue;
|
|
29
|
+
export declare function AuthProvider({ children }: AuthProviderProps): import("react").JSX.Element;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"AAEA,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAIlD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAClH,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACvG,eAAe,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACxK,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED,UAAU,iBAAiB;IACzB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAMD,eAAO,MAAM,OAAO,QAAO,gBAM1B,CAAC;AAmBF,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,+BAqH3D"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext, useEffect, useState, useMemo, useCallback, } from "react";
|
|
4
|
+
import { getSupabaseBrowserClient } from "./client";
|
|
5
|
+
// ─── Context ───────────────────────────────────────────
|
|
6
|
+
const AuthContext = createContext(null);
|
|
7
|
+
export const useAuth = () => {
|
|
8
|
+
const context = useContext(AuthContext);
|
|
9
|
+
if (!context) {
|
|
10
|
+
throw new Error("useAuth must be used within AuthProvider");
|
|
11
|
+
}
|
|
12
|
+
return context;
|
|
13
|
+
};
|
|
14
|
+
// ─── Sentry helper (safe fallback) ─────────────────────
|
|
15
|
+
async function updateSentryUser(user) {
|
|
16
|
+
try {
|
|
17
|
+
const Sentry = await import("@sentry/nextjs");
|
|
18
|
+
if (user) {
|
|
19
|
+
Sentry.setUser({ id: user.id, email: user.email ?? undefined });
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
Sentry.setUser(null);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// @sentry/nextjs is not installed — silently skip
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// ─── Provider ──────────────────────────────────────────
|
|
30
|
+
export function AuthProvider({ children }) {
|
|
31
|
+
const [user, setUser] = useState(null);
|
|
32
|
+
const [loading, setLoading] = useState(true);
|
|
33
|
+
const supabase = getSupabaseBrowserClient();
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
supabase.auth.getSession().then(({ data: { session } }) => {
|
|
36
|
+
setUser(session?.user ?? null);
|
|
37
|
+
setLoading(false);
|
|
38
|
+
});
|
|
39
|
+
const { data: { subscription }, } = supabase.auth.onAuthStateChange((event, session) => {
|
|
40
|
+
if (event === "PASSWORD_RECOVERY")
|
|
41
|
+
return;
|
|
42
|
+
const currentUser = session?.user ?? null;
|
|
43
|
+
setUser(currentUser);
|
|
44
|
+
setLoading(false);
|
|
45
|
+
updateSentryUser(currentUser);
|
|
46
|
+
});
|
|
47
|
+
return () => subscription.unsubscribe();
|
|
48
|
+
}, [supabase]);
|
|
49
|
+
const signInWithGoogle = useCallback(async ({ redirectTo } = {}) => {
|
|
50
|
+
const { data, error } = await supabase.auth.signInWithOAuth({
|
|
51
|
+
provider: "google",
|
|
52
|
+
options: {
|
|
53
|
+
redirectTo: redirectTo || `${globalThis.location.origin}/auth/callback`,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
if (error)
|
|
57
|
+
throw error;
|
|
58
|
+
return data;
|
|
59
|
+
}, [supabase]);
|
|
60
|
+
const signInWithEmail = useCallback(async (email, password) => {
|
|
61
|
+
const { data, error } = await supabase.auth.signInWithPassword({
|
|
62
|
+
email,
|
|
63
|
+
password,
|
|
64
|
+
});
|
|
65
|
+
if (error)
|
|
66
|
+
throw error;
|
|
67
|
+
return data;
|
|
68
|
+
}, [supabase]);
|
|
69
|
+
const signUpWithEmail = useCallback(async (email, password, fullName, { emailRedirectTo } = {}) => {
|
|
70
|
+
const { data, error } = await supabase.auth.signUp({
|
|
71
|
+
email,
|
|
72
|
+
password,
|
|
73
|
+
options: {
|
|
74
|
+
data: { full_name: fullName },
|
|
75
|
+
emailRedirectTo: emailRedirectTo || `${globalThis.location.origin}/auth/callback`,
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
if (error)
|
|
79
|
+
throw error;
|
|
80
|
+
return data;
|
|
81
|
+
}, [supabase]);
|
|
82
|
+
const resetPassword = useCallback(async (email) => {
|
|
83
|
+
const { error } = await supabase.auth.resetPasswordForEmail(email, {
|
|
84
|
+
redirectTo: `${globalThis.location.origin}/auth/reset-password`,
|
|
85
|
+
});
|
|
86
|
+
if (error)
|
|
87
|
+
throw error;
|
|
88
|
+
}, [supabase]);
|
|
89
|
+
const signOut = useCallback(async () => {
|
|
90
|
+
const { error } = await supabase.auth.signOut();
|
|
91
|
+
if (error)
|
|
92
|
+
throw error;
|
|
93
|
+
}, [supabase]);
|
|
94
|
+
const value = useMemo(() => ({
|
|
95
|
+
user,
|
|
96
|
+
loading,
|
|
97
|
+
signInWithGoogle,
|
|
98
|
+
signInWithEmail,
|
|
99
|
+
signUpWithEmail,
|
|
100
|
+
resetPassword,
|
|
101
|
+
signOut,
|
|
102
|
+
}), [
|
|
103
|
+
user,
|
|
104
|
+
loading,
|
|
105
|
+
signInWithGoogle,
|
|
106
|
+
signInWithEmail,
|
|
107
|
+
signUpWithEmail,
|
|
108
|
+
resetPassword,
|
|
109
|
+
signOut,
|
|
110
|
+
]);
|
|
111
|
+
return _jsx(AuthContext.Provider, { value: value, children: children });
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.tsx"],"names":[],"mappings":"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"}
|
package/dist/guard.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { NextResponse } from "next/server";
|
|
2
|
+
import type { NextRequest } from "next/server";
|
|
3
|
+
export declare const COMPREHENSIVE_MATCHER: string[];
|
|
4
|
+
export interface AuthGuardOptions {
|
|
5
|
+
publicPaths?: string[];
|
|
6
|
+
isHub?: boolean;
|
|
7
|
+
hubUrl?: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function createAuthGuard({ publicPaths, isHub, hubUrl, }?: AuthGuardOptions): (request: NextRequest) => Promise<NextResponse>;
|
|
10
|
+
//# sourceMappingURL=guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,eAAO,MAAM,qBAAqB,UAEjC,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,eAAe,CAAC,EAC9B,WAAgB,EAChB,KAAa,EACb,MAAM,GACP,GAAE,gBAAqB,IAOM,SAAS,WAAW,KAAG,OAAO,CAAC,YAAY,CAAC,CAuEzE"}
|
package/dist/guard.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { createServerClient } from "@supabase/ssr";
|
|
2
|
+
import { NextResponse } from "next/server";
|
|
3
|
+
export const COMPREHENSIVE_MATCHER = [
|
|
4
|
+
"/((?!_next/static|_next/image|favicon\\.ico|manifest\\.json|sw\\.js|icons/|ort/|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|wasm|mjs)$).*)",
|
|
5
|
+
];
|
|
6
|
+
export function createAuthGuard({ publicPaths = [], isHub = false, hubUrl, } = {}) {
|
|
7
|
+
function isPublicPath(pathname) {
|
|
8
|
+
return publicPaths.some((p) => pathname === p || pathname.startsWith(p + "/"));
|
|
9
|
+
}
|
|
10
|
+
return async function proxy(request) {
|
|
11
|
+
const requestHeaders = new Headers(request.headers);
|
|
12
|
+
requestHeaders.delete("x-middleware-subrequest");
|
|
13
|
+
let response = NextResponse.next({
|
|
14
|
+
request: { headers: requestHeaders },
|
|
15
|
+
});
|
|
16
|
+
const { pathname } = request.nextUrl;
|
|
17
|
+
if (isPublicPath(pathname)) {
|
|
18
|
+
return response;
|
|
19
|
+
}
|
|
20
|
+
if (pathname.startsWith("/api/") &&
|
|
21
|
+
request.headers.get("authorization")?.startsWith("Bearer ")) {
|
|
22
|
+
return response;
|
|
23
|
+
}
|
|
24
|
+
const supabase = createServerClient(process.env.NEXT_PUBLIC_SUPABASE_URL, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, {
|
|
25
|
+
cookieOptions: process.env.COOKIE_DOMAIN
|
|
26
|
+
? { domain: process.env.COOKIE_DOMAIN }
|
|
27
|
+
: undefined,
|
|
28
|
+
cookies: {
|
|
29
|
+
getAll() {
|
|
30
|
+
return request.cookies.getAll();
|
|
31
|
+
},
|
|
32
|
+
setAll(cookiesToSet) {
|
|
33
|
+
cookiesToSet.forEach(({ name, value, options }) => {
|
|
34
|
+
request.cookies.set(name, value);
|
|
35
|
+
response.cookies.set(name, value, options);
|
|
36
|
+
});
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
const { data: { user }, } = await supabase.auth.getUser();
|
|
41
|
+
if (!user) {
|
|
42
|
+
if (pathname.startsWith("/api/")) {
|
|
43
|
+
return NextResponse.json({ error: "Authentication required" }, { status: 401 });
|
|
44
|
+
}
|
|
45
|
+
if (isHub) {
|
|
46
|
+
const loginUrl = new URL("/login", request.url);
|
|
47
|
+
loginUrl.searchParams.set("redirect", pathname);
|
|
48
|
+
return NextResponse.redirect(loginUrl);
|
|
49
|
+
}
|
|
50
|
+
const loginUrl = new URL(`${hubUrl}/login`);
|
|
51
|
+
loginUrl.searchParams.set("redirect", request.url);
|
|
52
|
+
return NextResponse.redirect(loginUrl);
|
|
53
|
+
}
|
|
54
|
+
if (isHub && pathname === "/login") {
|
|
55
|
+
return NextResponse.redirect(new URL("/", request.url));
|
|
56
|
+
}
|
|
57
|
+
return response;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../src/guard.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SupabaseClient, User } from "@supabase/supabase-js";
|
|
2
|
+
export interface ServerUserResult {
|
|
3
|
+
user: User | null;
|
|
4
|
+
supabase: SupabaseClient;
|
|
5
|
+
}
|
|
6
|
+
export declare function getServerUser(): Promise<ServerUserResult>;
|
|
7
|
+
export declare function requireServerAuth(hubUrl?: string): Promise<{
|
|
8
|
+
user: User;
|
|
9
|
+
supabase: SupabaseClient;
|
|
10
|
+
}>;
|
|
11
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAMlE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAmC/D;AAED,wBAAsB,iBAAiB,CACrC,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE,CAAC,CAYnD"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { createServerClient } from "@supabase/ssr";
|
|
2
|
+
import { cookies } from "next/headers";
|
|
3
|
+
const COOKIE_OPTIONS = process.env.COOKIE_DOMAIN
|
|
4
|
+
? { domain: process.env.COOKIE_DOMAIN }
|
|
5
|
+
: undefined;
|
|
6
|
+
export async function getServerUser() {
|
|
7
|
+
const cookieStore = await cookies();
|
|
8
|
+
const supabase = createServerClient(process.env.NEXT_PUBLIC_SUPABASE_URL, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY, {
|
|
9
|
+
cookieOptions: COOKIE_OPTIONS,
|
|
10
|
+
cookies: {
|
|
11
|
+
getAll() {
|
|
12
|
+
return cookieStore.getAll();
|
|
13
|
+
},
|
|
14
|
+
setAll(cookiesToSet) {
|
|
15
|
+
try {
|
|
16
|
+
cookiesToSet.forEach(({ name, value, options }) => cookieStore.set(name, value, options));
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// setAll called from a Server Component — safe to ignore.
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
const { data: { user }, error, } = await supabase.auth.getUser();
|
|
25
|
+
if (error || !user) {
|
|
26
|
+
return { user: null, supabase };
|
|
27
|
+
}
|
|
28
|
+
return { user, supabase };
|
|
29
|
+
}
|
|
30
|
+
export async function requireServerAuth(hubUrl) {
|
|
31
|
+
const { redirect } = await import("next/navigation");
|
|
32
|
+
const { user, supabase } = await getServerUser();
|
|
33
|
+
if (!user) {
|
|
34
|
+
redirect(hubUrl ? `${hubUrl}/login` : "/login");
|
|
35
|
+
// redirect() throws internally — this satisfies TypeScript narrowing
|
|
36
|
+
throw new Error("Redirect should have been thrown");
|
|
37
|
+
}
|
|
38
|
+
return { user, supabase };
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa;IAC9C,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,aAAuB,EAAE;IACjD,CAAC,CAAC,SAAS,CAAC;AAOd,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,WAAW,GAAG,MAAM,OAAO,EAAE,CAAC;IAEpC,MAAM,QAAQ,GAAG,kBAAkB,CACjC,OAAO,CAAC,GAAG,CAAC,wBAAyB,EACrC,OAAO,CAAC,GAAG,CAAC,6BAA8B,EAC1C;QACE,aAAa,EAAE,cAAc;QAC7B,OAAO,EAAE;YACP,MAAM;gBACJ,OAAO,WAAW,CAAC,MAAM,EAAE,CAAC;YAC9B,CAAC;YACD,MAAM,CAAC,YAAY;gBACjB,IAAI,CAAC;oBACH,YAAY,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAChD,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,CACtC,CAAC;gBACJ,CAAC;gBAAC,MAAM,CAAC;oBACP,0DAA0D;gBAC5D,CAAC;YACH,CAAC;SACF;KACF,CACF,CAAC;IAEF,MAAM,EACJ,IAAI,EAAE,EAAE,IAAI,EAAE,EACd,KAAK,GACN,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IAElC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;QACnB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAClC,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAe;IAEf,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;IAErD,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,aAAa,EAAE,CAAC;IAEjD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAChD,qEAAqE;QACrE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AAC5B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lifelens/auth",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Universal auth SDK for the LifeLens ecosystem — works across any Next.js app, independent repos, and mobile apps",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"private": false,
|
|
7
|
+
"publishConfig": {
|
|
8
|
+
"access": "public"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "./dist/context.js",
|
|
12
|
+
"types": "./dist/context.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/context.d.ts",
|
|
16
|
+
"import": "./dist/context.js"
|
|
17
|
+
},
|
|
18
|
+
"./client": {
|
|
19
|
+
"types": "./dist/client.d.ts",
|
|
20
|
+
"import": "./dist/client.js"
|
|
21
|
+
},
|
|
22
|
+
"./server": {
|
|
23
|
+
"types": "./dist/server.d.ts",
|
|
24
|
+
"import": "./dist/server.js"
|
|
25
|
+
},
|
|
26
|
+
"./context": {
|
|
27
|
+
"types": "./dist/context.d.ts",
|
|
28
|
+
"import": "./dist/context.js"
|
|
29
|
+
},
|
|
30
|
+
"./guard": {
|
|
31
|
+
"types": "./dist/guard.d.ts",
|
|
32
|
+
"import": "./dist/guard.js"
|
|
33
|
+
},
|
|
34
|
+
"./bridge": {
|
|
35
|
+
"types": "./dist/bridge.d.ts",
|
|
36
|
+
"import": "./dist/bridge.js"
|
|
37
|
+
},
|
|
38
|
+
"./callback": {
|
|
39
|
+
"types": "./dist/callback.d.ts",
|
|
40
|
+
"import": "./dist/callback.js"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"dist"
|
|
45
|
+
],
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsc",
|
|
48
|
+
"clean": "rimraf dist",
|
|
49
|
+
"prepublishOnly": "npm run build"
|
|
50
|
+
},
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@supabase/ssr": "^0.7.0",
|
|
53
|
+
"@supabase/supabase-js": "^2.80.0"
|
|
54
|
+
},
|
|
55
|
+
"peerDependencies": {
|
|
56
|
+
"next": "^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
57
|
+
"react": "^18.0.0 || ^19.0.0"
|
|
58
|
+
},
|
|
59
|
+
"peerDependenciesMeta": {
|
|
60
|
+
"next": {
|
|
61
|
+
"optional": true
|
|
62
|
+
},
|
|
63
|
+
"react": {
|
|
64
|
+
"optional": true
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@sentry/nextjs": "^10.61.0",
|
|
69
|
+
"@types/node": "^22.20.0",
|
|
70
|
+
"@types/react": "^19.2.17",
|
|
71
|
+
"@types/react-dom": "^19.2.3",
|
|
72
|
+
"next": "^16.2.9",
|
|
73
|
+
"react": "^19.2.7",
|
|
74
|
+
"rimraf": "^5.0.0",
|
|
75
|
+
"typescript": "^5.3.0"
|
|
76
|
+
},
|
|
77
|
+
"repository": {
|
|
78
|
+
"type": "git",
|
|
79
|
+
"url": "https://github.com/lifelens/lifelens-auth"
|
|
80
|
+
}
|
|
81
|
+
}
|