@oauth42/next 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/index.mjs ADDED
@@ -0,0 +1,260 @@
1
+ // src/provider.ts
2
+ function OAuth42Provider(options) {
3
+ const issuer = options.issuer || process.env.OAUTH42_ISSUER || "https://oauth42.com";
4
+ const baseUrl = issuer.replace(/\/$/, "");
5
+ return {
6
+ id: "oauth42",
7
+ name: "OAuth42",
8
+ type: "oauth",
9
+ version: "2.0",
10
+ // Use OIDC discovery to automatically find endpoints
11
+ wellKnown: `${baseUrl}/.well-known/openid-configuration`,
12
+ // Also set individual endpoints for compatibility
13
+ authorization: {
14
+ url: `${baseUrl}/oauth2/authorize`,
15
+ params: {
16
+ scope: (options.scopes || ["openid", "profile", "email"]).join(" "),
17
+ response_type: "code"
18
+ }
19
+ },
20
+ token: `${baseUrl}/oauth2/token`,
21
+ userinfo: `${baseUrl}/oauth2/userinfo`,
22
+ client: {
23
+ id: options.clientId,
24
+ secret: options.clientSecret,
25
+ token_endpoint_auth_method: "client_secret_post",
26
+ id_token_signed_response_alg: "HS256"
27
+ // OAuth42 uses HS256 for ID tokens
28
+ },
29
+ issuer: baseUrl,
30
+ checks: options.pkceEnabled !== false ? ["pkce", "state"] : ["state"],
31
+ profile(profile, tokens) {
32
+ return {
33
+ id: profile.sub || profile.id || profile.email,
34
+ email: profile.email,
35
+ emailVerified: profile.email_verified ? /* @__PURE__ */ new Date() : null,
36
+ name: profile.name || `${profile.given_name || ""} ${profile.family_name || ""}`.trim(),
37
+ image: profile.picture
38
+ };
39
+ },
40
+ style: {
41
+ logo: "/oauth42-logo.svg",
42
+ bg: "#1e40af",
43
+ text: "#ffffff"
44
+ },
45
+ options
46
+ };
47
+ }
48
+
49
+ // src/server/auth.ts
50
+ import NextAuthDefault from "next-auth";
51
+
52
+ // src/server/session.ts
53
+ import { getServerSession as getNextAuthSession } from "next-auth";
54
+ async function getOAuth42Session(...args) {
55
+ return getNextAuthSession(...args);
56
+ }
57
+ function withOAuth42Session(handler, authOptions) {
58
+ return async (req, res) => {
59
+ const session = await getOAuth42Session(req, res, authOptions);
60
+ if (!session) {
61
+ return res.status(401).json({ error: "Unauthorized" });
62
+ }
63
+ return handler(req, res, session);
64
+ };
65
+ }
66
+ function withOAuth42ServerSideProps(getServerSideProps, authOptions) {
67
+ return async (context) => {
68
+ const session = await getOAuth42Session(
69
+ context.req,
70
+ context.res,
71
+ authOptions
72
+ );
73
+ if (!session) {
74
+ return {
75
+ redirect: {
76
+ destination: "/auth/signin",
77
+ permanent: false
78
+ }
79
+ };
80
+ }
81
+ return getServerSideProps(context, session);
82
+ };
83
+ }
84
+
85
+ // src/server/auth.ts
86
+ var NextAuth = NextAuthDefault.default || NextAuthDefault;
87
+ function createAuth(options = {}) {
88
+ const clientId = options.clientId || process.env.OAUTH42_CLIENT_ID;
89
+ const clientSecret = options.clientSecret || process.env.OAUTH42_CLIENT_SECRET;
90
+ if (!clientId || !clientSecret) {
91
+ throw new Error(
92
+ "OAuth42 client credentials are required. Set OAUTH42_CLIENT_ID and OAUTH42_CLIENT_SECRET environment variables or pass them in the options."
93
+ );
94
+ }
95
+ const authOptions = {
96
+ providers: [
97
+ OAuth42Provider({
98
+ clientId,
99
+ clientSecret,
100
+ issuer: options.issuer,
101
+ scopes: options.scopes,
102
+ pkceEnabled: options.pkceEnabled
103
+ })
104
+ ],
105
+ callbacks: {
106
+ async jwt({ token, account, profile }) {
107
+ if (account) {
108
+ token.accessToken = account.access_token;
109
+ token.refreshToken = account.refresh_token;
110
+ token.expiresAt = account.expires_at;
111
+ token.idToken = account.id_token;
112
+ }
113
+ if (profile) {
114
+ const oauth42Profile = profile;
115
+ token.email = oauth42Profile.email;
116
+ token.username = oauth42Profile.username;
117
+ token.emailVerified = oauth42Profile.email_verified;
118
+ }
119
+ if (options.callbacks?.jwt) {
120
+ return options.callbacks.jwt({ token, account, profile });
121
+ }
122
+ return token;
123
+ },
124
+ async session({ session, token }) {
125
+ session.accessToken = token.accessToken;
126
+ session.idToken = token.idToken;
127
+ if (session.user) {
128
+ session.user.email = token.email;
129
+ session.user.username = token.username;
130
+ session.user.emailVerified = token.emailVerified;
131
+ }
132
+ if (options.callbacks?.session) {
133
+ return options.callbacks.session({ session, token });
134
+ }
135
+ return session;
136
+ },
137
+ ...options.callbacks
138
+ },
139
+ pages: {
140
+ signIn: "/auth/signin",
141
+ signOut: "/auth/signout",
142
+ error: "/auth/error",
143
+ ...options.pages
144
+ },
145
+ session: {
146
+ strategy: "jwt",
147
+ ...options.session
148
+ },
149
+ debug: options.debug || process.env.NODE_ENV === "development",
150
+ secret: process.env.NEXTAUTH_SECRET
151
+ };
152
+ return {
153
+ auth: authOptions,
154
+ handlers: NextAuth(authOptions)
155
+ };
156
+ }
157
+ var getServerSession = getOAuth42Session;
158
+ async function refreshAccessToken(token, clientId, clientSecret, issuer) {
159
+ try {
160
+ const baseUrl = issuer || process.env.OAUTH42_ISSUER || "https://oauth42.com";
161
+ const tokenUrl = `${baseUrl}/oauth2/token`;
162
+ const fetchOptions = {
163
+ method: "POST",
164
+ headers: {
165
+ "Content-Type": "application/x-www-form-urlencoded"
166
+ },
167
+ body: new URLSearchParams({
168
+ grant_type: "refresh_token",
169
+ refresh_token: token.refreshToken,
170
+ client_id: clientId,
171
+ client_secret: clientSecret
172
+ })
173
+ };
174
+ if (process.env.NODE_ENV !== "production" && tokenUrl.startsWith("https://")) {
175
+ const https = await import("https");
176
+ fetchOptions.agent = new https.Agent({
177
+ rejectUnauthorized: false
178
+ });
179
+ }
180
+ const response = await fetch(tokenUrl, fetchOptions);
181
+ const refreshedTokens = await response.json();
182
+ if (!response.ok) {
183
+ throw refreshedTokens;
184
+ }
185
+ return {
186
+ ...token,
187
+ accessToken: refreshedTokens.access_token,
188
+ refreshToken: refreshedTokens.refresh_token ?? token.refreshToken,
189
+ // Store expiration time in seconds (Unix timestamp)
190
+ expiresAt: Math.floor(Date.now() / 1e3) + (refreshedTokens.expires_in || 3600),
191
+ // Explicitly remove any error property on successful refresh
192
+ error: void 0
193
+ };
194
+ } catch (error) {
195
+ console.error("Failed to refresh access token:", error);
196
+ return {
197
+ ...token,
198
+ error: "RefreshAccessTokenError"
199
+ };
200
+ }
201
+ }
202
+
203
+ // src/server/middleware.ts
204
+ import { NextResponse } from "next/server";
205
+ import { getToken } from "next-auth/jwt";
206
+ function withOAuth42Auth(options = {}) {
207
+ return async function middleware(req) {
208
+ const token = await getToken({
209
+ req,
210
+ secret: process.env.NEXTAUTH_SECRET
211
+ });
212
+ const pathname = req.nextUrl.pathname;
213
+ if (options.publicPaths?.some((path) => pathname.startsWith(path))) {
214
+ return NextResponse.next();
215
+ }
216
+ const needsProtection = options.protectedPaths ? options.protectedPaths.some((path) => pathname.startsWith(path)) : true;
217
+ if (!needsProtection) {
218
+ return NextResponse.next();
219
+ }
220
+ let isAuthorized = !!token;
221
+ if (options.callbacks?.authorized) {
222
+ isAuthorized = await options.callbacks.authorized({ token, req });
223
+ }
224
+ if (!isAuthorized) {
225
+ const signInUrl = options.pages?.signIn || "/auth/signin";
226
+ const url = new URL(signInUrl, req.url);
227
+ url.searchParams.set("callbackUrl", pathname);
228
+ return NextResponse.redirect(url);
229
+ }
230
+ return NextResponse.next();
231
+ };
232
+ }
233
+ function createMiddlewareConfig(protectedPaths = ["/protected"], publicPaths = ["/auth", "/api/auth"]) {
234
+ return {
235
+ matcher: [
236
+ /*
237
+ * Match all request paths except for the ones starting with:
238
+ * - _next/static (static files)
239
+ * - _next/image (image optimization files)
240
+ * - favicon.ico (favicon file)
241
+ * - public folder
242
+ */
243
+ "/((?!_next/static|_next/image|favicon.ico|public).*)"
244
+ ],
245
+ protectedPaths,
246
+ publicPaths
247
+ };
248
+ }
249
+ export {
250
+ OAuth42Provider,
251
+ createAuth,
252
+ createMiddlewareConfig,
253
+ getOAuth42Session,
254
+ getServerSession,
255
+ refreshAccessToken,
256
+ withOAuth42Auth,
257
+ withOAuth42ServerSideProps,
258
+ withOAuth42Session
259
+ };
260
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/provider.ts","../src/server/auth.ts","../src/server/session.ts","../src/server/middleware.ts"],"sourcesContent":["import type { OAuthConfig, OAuthUserConfig } from 'next-auth/providers/oauth';\n\nexport interface OAuth42Profile {\n sub: string;\n email: string;\n email_verified?: boolean;\n name?: string;\n given_name?: string;\n family_name?: string;\n picture?: string;\n username?: string;\n id?: string;\n}\n\nexport interface OAuth42ProviderOptions {\n clientId: string;\n clientSecret: string;\n issuer?: string;\n authorizationUrl?: string;\n tokenUrl?: string;\n userinfoUrl?: string;\n scopes?: string[];\n pkceEnabled?: boolean;\n}\n\nexport function OAuth42Provider<P extends OAuth42Profile>(\n options: OAuthUserConfig<P> & Partial<OAuth42ProviderOptions>\n): OAuthConfig<P> {\n const issuer = options.issuer || process.env.OAUTH42_ISSUER || 'https://oauth42.com';\n const baseUrl = issuer.replace(/\\/$/, '');\n \n return {\n id: 'oauth42',\n name: 'OAuth42',\n type: 'oauth',\n version: '2.0',\n \n // Use OIDC discovery to automatically find endpoints\n wellKnown: `${baseUrl}/.well-known/openid-configuration`,\n \n // Also set individual endpoints for compatibility\n authorization: {\n url: `${baseUrl}/oauth2/authorize`,\n params: {\n scope: (options.scopes || ['openid', 'profile', 'email']).join(' '),\n response_type: 'code',\n },\n },\n token: `${baseUrl}/oauth2/token`,\n userinfo: `${baseUrl}/oauth2/userinfo`,\n \n client: {\n id: options.clientId,\n secret: options.clientSecret,\n token_endpoint_auth_method: 'client_secret_post',\n id_token_signed_response_alg: 'HS256', // OAuth42 uses HS256 for ID tokens\n },\n \n issuer: baseUrl,\n \n checks: options.pkceEnabled !== false ? ['pkce', 'state'] : ['state'],\n \n profile(profile: OAuth42Profile, tokens: any) {\n return {\n id: profile.sub || profile.id || profile.email,\n email: profile.email,\n emailVerified: profile.email_verified ? new Date() : null,\n name: profile.name || `${profile.given_name || ''} ${profile.family_name || ''}`.trim(),\n image: profile.picture,\n };\n },\n \n style: {\n logo: '/oauth42-logo.svg',\n bg: '#1e40af',\n text: '#ffffff',\n },\n \n options,\n };\n}","import NextAuthDefault from 'next-auth';\nimport type { NextAuthOptions } from 'next-auth';\nimport { OAuth42Provider, OAuth42Profile } from '../provider';\nimport { getOAuth42Session } from './session';\n\n// Handle both CommonJS and ESM exports\nconst NextAuth = (NextAuthDefault as any).default || NextAuthDefault;\n\nexport { type NextAuthOptions };\n\nexport interface CreateAuthOptions {\n clientId?: string;\n clientSecret?: string;\n issuer?: string;\n scopes?: string[];\n pkceEnabled?: boolean;\n debug?: boolean;\n callbacks?: NextAuthOptions['callbacks'];\n pages?: NextAuthOptions['pages'];\n session?: NextAuthOptions['session'];\n}\n\n/**\n * Create a pre-configured NextAuth instance for OAuth42\n * This provides a simplified setup with sensible defaults\n */\nexport function createAuth(options: CreateAuthOptions = {}) {\n const clientId = options.clientId || process.env.OAUTH42_CLIENT_ID;\n const clientSecret = options.clientSecret || process.env.OAUTH42_CLIENT_SECRET;\n \n if (!clientId || !clientSecret) {\n throw new Error(\n 'OAuth42 client credentials are required. ' +\n 'Set OAUTH42_CLIENT_ID and OAUTH42_CLIENT_SECRET environment variables ' +\n 'or pass them in the options.'\n );\n }\n \n const authOptions: NextAuthOptions = {\n providers: [\n OAuth42Provider({\n clientId,\n clientSecret,\n issuer: options.issuer,\n scopes: options.scopes,\n pkceEnabled: options.pkceEnabled,\n }),\n ],\n \n callbacks: {\n async jwt({ token, account, profile }) {\n // Store OAuth tokens in the JWT\n if (account) {\n token.accessToken = account.access_token;\n token.refreshToken = account.refresh_token;\n token.expiresAt = account.expires_at;\n token.idToken = account.id_token;\n }\n \n // Add user profile data\n if (profile) {\n const oauth42Profile = profile as OAuth42Profile;\n token.email = oauth42Profile.email;\n token.username = oauth42Profile.username;\n token.emailVerified = oauth42Profile.email_verified;\n }\n \n // Call custom callback if provided\n if (options.callbacks?.jwt) {\n return options.callbacks.jwt({ token, account, profile } as any);\n }\n \n return token;\n },\n \n async session({ session, token }) {\n // Add OAuth42-specific data to session\n session.accessToken = token.accessToken as string;\n session.idToken = token.idToken as string;\n \n if (session.user) {\n session.user.email = token.email as string;\n session.user.username = token.username as string;\n session.user.emailVerified = token.emailVerified as boolean;\n }\n \n // Call custom callback if provided\n if (options.callbacks?.session) {\n return options.callbacks.session({ session, token } as any);\n }\n \n return session;\n },\n \n ...options.callbacks,\n },\n \n pages: {\n signIn: '/auth/signin',\n signOut: '/auth/signout',\n error: '/auth/error',\n ...options.pages,\n },\n \n session: {\n strategy: 'jwt',\n ...options.session,\n },\n \n debug: options.debug || process.env.NODE_ENV === 'development',\n \n secret: process.env.NEXTAUTH_SECRET,\n };\n \n // Return the configuration and a function to create handlers\n return {\n auth: authOptions,\n handlers: NextAuth(authOptions),\n };\n}\n\n/**\n * Create NextAuth handlers for API routes\n */\nexport function createHandlers(authOptions: NextAuthOptions) {\n const handler = NextAuth(authOptions);\n return { GET: handler, POST: handler };\n}\n\n/**\n * Helper to get the current session server-side\n * @deprecated Use getOAuth42Session instead - this is now just an alias for backward compatibility\n * \n * This function is maintained for backward compatibility but internally\n * calls getOAuth42Session which properly handles both App Router and Pages Router\n */\nexport const getServerSession = getOAuth42Session;\n\n/**\n * Token refresh helper\n */\nexport async function refreshAccessToken(token: any, clientId: string, clientSecret: string, issuer?: string) {\n try {\n const baseUrl = issuer || process.env.OAUTH42_ISSUER || 'https://oauth42.com';\n const tokenUrl = `${baseUrl}/oauth2/token`;\n \n // In development, we need to handle self-signed certificates\n const fetchOptions: any = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: token.refreshToken,\n client_id: clientId,\n client_secret: clientSecret,\n }),\n };\n \n // Add agent for self-signed certificates in development\n if (process.env.NODE_ENV !== 'production' && tokenUrl.startsWith('https://')) {\n const https = await import('https');\n fetchOptions.agent = new https.Agent({\n rejectUnauthorized: false\n });\n }\n \n const response = await fetch(tokenUrl, fetchOptions);\n const refreshedTokens = await response.json();\n \n if (!response.ok) {\n throw refreshedTokens;\n }\n \n return {\n ...token,\n accessToken: refreshedTokens.access_token,\n refreshToken: refreshedTokens.refresh_token ?? token.refreshToken,\n // Store expiration time in seconds (Unix timestamp)\n expiresAt: Math.floor(Date.now() / 1000) + (refreshedTokens.expires_in || 3600),\n // Explicitly remove any error property on successful refresh\n error: undefined,\n };\n } catch (error) {\n console.error('Failed to refresh access token:', error);\n return {\n ...token,\n error: 'RefreshAccessTokenError',\n };\n }\n}","import { getServerSession as getNextAuthSession } from 'next-auth';\nimport { NextAuthOptions } from 'next-auth';\nimport { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from 'next';\n\n/**\n * Get the OAuth42 session server-side\n * \n * This is the primary method for retrieving sessions in OAuth42 SDK.\n * Supports both Pages Router and App Router:\n * \n * App Router:\n * ```ts\n * const session = await getOAuth42Session(authOptions);\n * ```\n * \n * Pages Router:\n * ```ts\n * const session = await getOAuth42Session(req, res, authOptions);\n * ```\n */\nexport async function getOAuth42Session(\n ...args: \n | [GetServerSidePropsContext['req'], GetServerSidePropsContext['res'], NextAuthOptions]\n | [NextApiRequest, NextApiResponse, NextAuthOptions]\n | [NextAuthOptions]\n) {\n return getNextAuthSession(...args as any);\n}\n\n/**\n * Helper for protecting API routes\n */\nexport function withOAuth42Session(\n handler: (req: NextApiRequest, res: NextApiResponse, session: any) => Promise<void> | void,\n authOptions: NextAuthOptions\n) {\n return async (req: NextApiRequest, res: NextApiResponse) => {\n const session = await getOAuth42Session(req, res, authOptions);\n \n if (!session) {\n return res.status(401).json({ error: 'Unauthorized' });\n }\n \n return handler(req, res, session);\n };\n}\n\n/**\n * Helper for protecting server-side props\n */\nexport function withOAuth42ServerSideProps(\n getServerSideProps: (\n context: GetServerSidePropsContext,\n session: any\n ) => Promise<any>,\n authOptions: NextAuthOptions\n) {\n return async (context: GetServerSidePropsContext) => {\n const session = await getOAuth42Session(\n context.req,\n context.res,\n authOptions\n );\n \n if (!session) {\n return {\n redirect: {\n destination: '/auth/signin',\n permanent: false,\n },\n };\n }\n \n return getServerSideProps(context, session);\n };\n}","import { NextRequest, NextResponse } from 'next/server';\nimport { getToken } from 'next-auth/jwt';\n\nexport interface OAuth42AuthOptions {\n pages?: {\n signIn?: string;\n error?: string;\n };\n callbacks?: {\n authorized?: (params: { token: any; req: NextRequest }) => boolean | Promise<boolean>;\n };\n protectedPaths?: string[];\n publicPaths?: string[];\n}\n\n/**\n * Middleware helper for protecting routes with OAuth42\n */\nexport function withOAuth42Auth(options: OAuth42AuthOptions = {}) {\n return async function middleware(req: NextRequest) {\n const token = await getToken({ \n req: req as any, \n secret: process.env.NEXTAUTH_SECRET \n });\n \n const pathname = req.nextUrl.pathname;\n \n // Check if path is explicitly public\n if (options.publicPaths?.some(path => pathname.startsWith(path))) {\n return NextResponse.next();\n }\n \n // Check if path needs protection\n const needsProtection = options.protectedPaths\n ? options.protectedPaths.some(path => pathname.startsWith(path))\n : true; // Default to protecting all paths\n \n if (!needsProtection) {\n return NextResponse.next();\n }\n \n // Check authorization\n let isAuthorized = !!token;\n \n if (options.callbacks?.authorized) {\n isAuthorized = await options.callbacks.authorized({ token, req });\n }\n \n if (!isAuthorized) {\n const signInUrl = options.pages?.signIn || '/auth/signin';\n const url = new URL(signInUrl, req.url);\n url.searchParams.set('callbackUrl', pathname);\n return NextResponse.redirect(url);\n }\n \n return NextResponse.next();\n };\n}\n\n/**\n * Helper to create middleware configuration\n */\nexport function createMiddlewareConfig(\n protectedPaths: string[] = ['/protected'],\n publicPaths: string[] = ['/auth', '/api/auth']\n) {\n return {\n matcher: [\n /*\n * Match all request paths except for the ones starting with:\n * - _next/static (static files)\n * - _next/image (image optimization files)\n * - favicon.ico (favicon file)\n * - public folder\n */\n '/((?!_next/static|_next/image|favicon.ico|public).*)',\n ],\n protectedPaths,\n publicPaths,\n };\n}"],"mappings":"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","names":[]}
@@ -0,0 +1,5 @@
1
+ export { C as CreateAuthOptions, e as OAuth42AuthOptions, O as OAuth42Provider, c as createAuth, j as createHandlers, d as createMiddlewareConfig, f as getOAuth42Session, g as getServerSession, r as refreshAccessToken, w as withOAuth42Auth, i as withOAuth42ServerSideProps, h as withOAuth42Session } from '../index-xJCMwWtK.mjs';
2
+ export { default as NextAuth, NextAuthOptions } from 'next-auth';
3
+ import 'next';
4
+ import 'next-auth/providers/oauth';
5
+ import 'next/server';
@@ -0,0 +1,5 @@
1
+ export { C as CreateAuthOptions, e as OAuth42AuthOptions, O as OAuth42Provider, c as createAuth, j as createHandlers, d as createMiddlewareConfig, f as getOAuth42Session, g as getServerSession, r as refreshAccessToken, w as withOAuth42Auth, i as withOAuth42ServerSideProps, h as withOAuth42Session } from '../index-xJCMwWtK.js';
2
+ export { default as NextAuth, NextAuthOptions } from 'next-auth';
3
+ import 'next';
4
+ import 'next-auth/providers/oauth';
5
+ import 'next/server';
@@ -0,0 +1,316 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/server/index.ts
31
+ var server_exports = {};
32
+ __export(server_exports, {
33
+ NextAuth: () => import_next_auth3.default,
34
+ OAuth42Provider: () => OAuth42Provider,
35
+ createAuth: () => createAuth,
36
+ createHandlers: () => createHandlers,
37
+ createMiddlewareConfig: () => createMiddlewareConfig,
38
+ getOAuth42Session: () => getOAuth42Session,
39
+ getServerSession: () => getServerSession,
40
+ refreshAccessToken: () => refreshAccessToken,
41
+ withOAuth42Auth: () => withOAuth42Auth,
42
+ withOAuth42ServerSideProps: () => withOAuth42ServerSideProps,
43
+ withOAuth42Session: () => withOAuth42Session
44
+ });
45
+ module.exports = __toCommonJS(server_exports);
46
+
47
+ // src/server/auth.ts
48
+ var import_next_auth2 = __toESM(require("next-auth"));
49
+
50
+ // src/provider.ts
51
+ function OAuth42Provider(options) {
52
+ const issuer = options.issuer || process.env.OAUTH42_ISSUER || "https://oauth42.com";
53
+ const baseUrl = issuer.replace(/\/$/, "");
54
+ return {
55
+ id: "oauth42",
56
+ name: "OAuth42",
57
+ type: "oauth",
58
+ version: "2.0",
59
+ // Use OIDC discovery to automatically find endpoints
60
+ wellKnown: `${baseUrl}/.well-known/openid-configuration`,
61
+ // Also set individual endpoints for compatibility
62
+ authorization: {
63
+ url: `${baseUrl}/oauth2/authorize`,
64
+ params: {
65
+ scope: (options.scopes || ["openid", "profile", "email"]).join(" "),
66
+ response_type: "code"
67
+ }
68
+ },
69
+ token: `${baseUrl}/oauth2/token`,
70
+ userinfo: `${baseUrl}/oauth2/userinfo`,
71
+ client: {
72
+ id: options.clientId,
73
+ secret: options.clientSecret,
74
+ token_endpoint_auth_method: "client_secret_post",
75
+ id_token_signed_response_alg: "HS256"
76
+ // OAuth42 uses HS256 for ID tokens
77
+ },
78
+ issuer: baseUrl,
79
+ checks: options.pkceEnabled !== false ? ["pkce", "state"] : ["state"],
80
+ profile(profile, tokens) {
81
+ return {
82
+ id: profile.sub || profile.id || profile.email,
83
+ email: profile.email,
84
+ emailVerified: profile.email_verified ? /* @__PURE__ */ new Date() : null,
85
+ name: profile.name || `${profile.given_name || ""} ${profile.family_name || ""}`.trim(),
86
+ image: profile.picture
87
+ };
88
+ },
89
+ style: {
90
+ logo: "/oauth42-logo.svg",
91
+ bg: "#1e40af",
92
+ text: "#ffffff"
93
+ },
94
+ options
95
+ };
96
+ }
97
+
98
+ // src/server/session.ts
99
+ var import_next_auth = require("next-auth");
100
+ async function getOAuth42Session(...args) {
101
+ return (0, import_next_auth.getServerSession)(...args);
102
+ }
103
+ function withOAuth42Session(handler, authOptions) {
104
+ return async (req, res) => {
105
+ const session = await getOAuth42Session(req, res, authOptions);
106
+ if (!session) {
107
+ return res.status(401).json({ error: "Unauthorized" });
108
+ }
109
+ return handler(req, res, session);
110
+ };
111
+ }
112
+ function withOAuth42ServerSideProps(getServerSideProps, authOptions) {
113
+ return async (context) => {
114
+ const session = await getOAuth42Session(
115
+ context.req,
116
+ context.res,
117
+ authOptions
118
+ );
119
+ if (!session) {
120
+ return {
121
+ redirect: {
122
+ destination: "/auth/signin",
123
+ permanent: false
124
+ }
125
+ };
126
+ }
127
+ return getServerSideProps(context, session);
128
+ };
129
+ }
130
+
131
+ // src/server/auth.ts
132
+ var NextAuth = import_next_auth2.default.default || import_next_auth2.default;
133
+ function createAuth(options = {}) {
134
+ const clientId = options.clientId || process.env.OAUTH42_CLIENT_ID;
135
+ const clientSecret = options.clientSecret || process.env.OAUTH42_CLIENT_SECRET;
136
+ if (!clientId || !clientSecret) {
137
+ throw new Error(
138
+ "OAuth42 client credentials are required. Set OAUTH42_CLIENT_ID and OAUTH42_CLIENT_SECRET environment variables or pass them in the options."
139
+ );
140
+ }
141
+ const authOptions = {
142
+ providers: [
143
+ OAuth42Provider({
144
+ clientId,
145
+ clientSecret,
146
+ issuer: options.issuer,
147
+ scopes: options.scopes,
148
+ pkceEnabled: options.pkceEnabled
149
+ })
150
+ ],
151
+ callbacks: {
152
+ async jwt({ token, account, profile }) {
153
+ if (account) {
154
+ token.accessToken = account.access_token;
155
+ token.refreshToken = account.refresh_token;
156
+ token.expiresAt = account.expires_at;
157
+ token.idToken = account.id_token;
158
+ }
159
+ if (profile) {
160
+ const oauth42Profile = profile;
161
+ token.email = oauth42Profile.email;
162
+ token.username = oauth42Profile.username;
163
+ token.emailVerified = oauth42Profile.email_verified;
164
+ }
165
+ if (options.callbacks?.jwt) {
166
+ return options.callbacks.jwt({ token, account, profile });
167
+ }
168
+ return token;
169
+ },
170
+ async session({ session, token }) {
171
+ session.accessToken = token.accessToken;
172
+ session.idToken = token.idToken;
173
+ if (session.user) {
174
+ session.user.email = token.email;
175
+ session.user.username = token.username;
176
+ session.user.emailVerified = token.emailVerified;
177
+ }
178
+ if (options.callbacks?.session) {
179
+ return options.callbacks.session({ session, token });
180
+ }
181
+ return session;
182
+ },
183
+ ...options.callbacks
184
+ },
185
+ pages: {
186
+ signIn: "/auth/signin",
187
+ signOut: "/auth/signout",
188
+ error: "/auth/error",
189
+ ...options.pages
190
+ },
191
+ session: {
192
+ strategy: "jwt",
193
+ ...options.session
194
+ },
195
+ debug: options.debug || process.env.NODE_ENV === "development",
196
+ secret: process.env.NEXTAUTH_SECRET
197
+ };
198
+ return {
199
+ auth: authOptions,
200
+ handlers: NextAuth(authOptions)
201
+ };
202
+ }
203
+ function createHandlers(authOptions) {
204
+ const handler = NextAuth(authOptions);
205
+ return { GET: handler, POST: handler };
206
+ }
207
+ var getServerSession = getOAuth42Session;
208
+ async function refreshAccessToken(token, clientId, clientSecret, issuer) {
209
+ try {
210
+ const baseUrl = issuer || process.env.OAUTH42_ISSUER || "https://oauth42.com";
211
+ const tokenUrl = `${baseUrl}/oauth2/token`;
212
+ const fetchOptions = {
213
+ method: "POST",
214
+ headers: {
215
+ "Content-Type": "application/x-www-form-urlencoded"
216
+ },
217
+ body: new URLSearchParams({
218
+ grant_type: "refresh_token",
219
+ refresh_token: token.refreshToken,
220
+ client_id: clientId,
221
+ client_secret: clientSecret
222
+ })
223
+ };
224
+ if (process.env.NODE_ENV !== "production" && tokenUrl.startsWith("https://")) {
225
+ const https = await import("https");
226
+ fetchOptions.agent = new https.Agent({
227
+ rejectUnauthorized: false
228
+ });
229
+ }
230
+ const response = await fetch(tokenUrl, fetchOptions);
231
+ const refreshedTokens = await response.json();
232
+ if (!response.ok) {
233
+ throw refreshedTokens;
234
+ }
235
+ return {
236
+ ...token,
237
+ accessToken: refreshedTokens.access_token,
238
+ refreshToken: refreshedTokens.refresh_token ?? token.refreshToken,
239
+ // Store expiration time in seconds (Unix timestamp)
240
+ expiresAt: Math.floor(Date.now() / 1e3) + (refreshedTokens.expires_in || 3600),
241
+ // Explicitly remove any error property on successful refresh
242
+ error: void 0
243
+ };
244
+ } catch (error) {
245
+ console.error("Failed to refresh access token:", error);
246
+ return {
247
+ ...token,
248
+ error: "RefreshAccessTokenError"
249
+ };
250
+ }
251
+ }
252
+
253
+ // src/server/index.ts
254
+ var import_next_auth3 = __toESM(require("next-auth"));
255
+
256
+ // src/server/middleware.ts
257
+ var import_server = require("next/server");
258
+ var import_jwt = require("next-auth/jwt");
259
+ function withOAuth42Auth(options = {}) {
260
+ return async function middleware(req) {
261
+ const token = await (0, import_jwt.getToken)({
262
+ req,
263
+ secret: process.env.NEXTAUTH_SECRET
264
+ });
265
+ const pathname = req.nextUrl.pathname;
266
+ if (options.publicPaths?.some((path) => pathname.startsWith(path))) {
267
+ return import_server.NextResponse.next();
268
+ }
269
+ const needsProtection = options.protectedPaths ? options.protectedPaths.some((path) => pathname.startsWith(path)) : true;
270
+ if (!needsProtection) {
271
+ return import_server.NextResponse.next();
272
+ }
273
+ let isAuthorized = !!token;
274
+ if (options.callbacks?.authorized) {
275
+ isAuthorized = await options.callbacks.authorized({ token, req });
276
+ }
277
+ if (!isAuthorized) {
278
+ const signInUrl = options.pages?.signIn || "/auth/signin";
279
+ const url = new URL(signInUrl, req.url);
280
+ url.searchParams.set("callbackUrl", pathname);
281
+ return import_server.NextResponse.redirect(url);
282
+ }
283
+ return import_server.NextResponse.next();
284
+ };
285
+ }
286
+ function createMiddlewareConfig(protectedPaths = ["/protected"], publicPaths = ["/auth", "/api/auth"]) {
287
+ return {
288
+ matcher: [
289
+ /*
290
+ * Match all request paths except for the ones starting with:
291
+ * - _next/static (static files)
292
+ * - _next/image (image optimization files)
293
+ * - favicon.ico (favicon file)
294
+ * - public folder
295
+ */
296
+ "/((?!_next/static|_next/image|favicon.ico|public).*)"
297
+ ],
298
+ protectedPaths,
299
+ publicPaths
300
+ };
301
+ }
302
+ // Annotate the CommonJS export names for ESM import in node:
303
+ 0 && (module.exports = {
304
+ NextAuth,
305
+ OAuth42Provider,
306
+ createAuth,
307
+ createHandlers,
308
+ createMiddlewareConfig,
309
+ getOAuth42Session,
310
+ getServerSession,
311
+ refreshAccessToken,
312
+ withOAuth42Auth,
313
+ withOAuth42ServerSideProps,
314
+ withOAuth42Session
315
+ });
316
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/server/index.ts","../../src/server/auth.ts","../../src/provider.ts","../../src/server/session.ts","../../src/server/middleware.ts"],"sourcesContent":["// Server-side exports\nexport { createAuth, createHandlers, getServerSession, refreshAccessToken } from './auth';\nexport type { CreateAuthOptions, NextAuthOptions } from './auth';\n\n// Re-export NextAuth from next-auth\nexport { default as NextAuth } from 'next-auth';\n\n// Re-export OAuth42Provider\nexport { OAuth42Provider } from '../provider';\n\nexport { withOAuth42Auth, createMiddlewareConfig } from './middleware';\nexport type { OAuth42AuthOptions } from './middleware';\n\nexport { getOAuth42Session, withOAuth42Session, withOAuth42ServerSideProps } from './session';","import NextAuthDefault from 'next-auth';\nimport type { NextAuthOptions } from 'next-auth';\nimport { OAuth42Provider, OAuth42Profile } from '../provider';\nimport { getOAuth42Session } from './session';\n\n// Handle both CommonJS and ESM exports\nconst NextAuth = (NextAuthDefault as any).default || NextAuthDefault;\n\nexport { type NextAuthOptions };\n\nexport interface CreateAuthOptions {\n clientId?: string;\n clientSecret?: string;\n issuer?: string;\n scopes?: string[];\n pkceEnabled?: boolean;\n debug?: boolean;\n callbacks?: NextAuthOptions['callbacks'];\n pages?: NextAuthOptions['pages'];\n session?: NextAuthOptions['session'];\n}\n\n/**\n * Create a pre-configured NextAuth instance for OAuth42\n * This provides a simplified setup with sensible defaults\n */\nexport function createAuth(options: CreateAuthOptions = {}) {\n const clientId = options.clientId || process.env.OAUTH42_CLIENT_ID;\n const clientSecret = options.clientSecret || process.env.OAUTH42_CLIENT_SECRET;\n \n if (!clientId || !clientSecret) {\n throw new Error(\n 'OAuth42 client credentials are required. ' +\n 'Set OAUTH42_CLIENT_ID and OAUTH42_CLIENT_SECRET environment variables ' +\n 'or pass them in the options.'\n );\n }\n \n const authOptions: NextAuthOptions = {\n providers: [\n OAuth42Provider({\n clientId,\n clientSecret,\n issuer: options.issuer,\n scopes: options.scopes,\n pkceEnabled: options.pkceEnabled,\n }),\n ],\n \n callbacks: {\n async jwt({ token, account, profile }) {\n // Store OAuth tokens in the JWT\n if (account) {\n token.accessToken = account.access_token;\n token.refreshToken = account.refresh_token;\n token.expiresAt = account.expires_at;\n token.idToken = account.id_token;\n }\n \n // Add user profile data\n if (profile) {\n const oauth42Profile = profile as OAuth42Profile;\n token.email = oauth42Profile.email;\n token.username = oauth42Profile.username;\n token.emailVerified = oauth42Profile.email_verified;\n }\n \n // Call custom callback if provided\n if (options.callbacks?.jwt) {\n return options.callbacks.jwt({ token, account, profile } as any);\n }\n \n return token;\n },\n \n async session({ session, token }) {\n // Add OAuth42-specific data to session\n session.accessToken = token.accessToken as string;\n session.idToken = token.idToken as string;\n \n if (session.user) {\n session.user.email = token.email as string;\n session.user.username = token.username as string;\n session.user.emailVerified = token.emailVerified as boolean;\n }\n \n // Call custom callback if provided\n if (options.callbacks?.session) {\n return options.callbacks.session({ session, token } as any);\n }\n \n return session;\n },\n \n ...options.callbacks,\n },\n \n pages: {\n signIn: '/auth/signin',\n signOut: '/auth/signout',\n error: '/auth/error',\n ...options.pages,\n },\n \n session: {\n strategy: 'jwt',\n ...options.session,\n },\n \n debug: options.debug || process.env.NODE_ENV === 'development',\n \n secret: process.env.NEXTAUTH_SECRET,\n };\n \n // Return the configuration and a function to create handlers\n return {\n auth: authOptions,\n handlers: NextAuth(authOptions),\n };\n}\n\n/**\n * Create NextAuth handlers for API routes\n */\nexport function createHandlers(authOptions: NextAuthOptions) {\n const handler = NextAuth(authOptions);\n return { GET: handler, POST: handler };\n}\n\n/**\n * Helper to get the current session server-side\n * @deprecated Use getOAuth42Session instead - this is now just an alias for backward compatibility\n * \n * This function is maintained for backward compatibility but internally\n * calls getOAuth42Session which properly handles both App Router and Pages Router\n */\nexport const getServerSession = getOAuth42Session;\n\n/**\n * Token refresh helper\n */\nexport async function refreshAccessToken(token: any, clientId: string, clientSecret: string, issuer?: string) {\n try {\n const baseUrl = issuer || process.env.OAUTH42_ISSUER || 'https://oauth42.com';\n const tokenUrl = `${baseUrl}/oauth2/token`;\n \n // In development, we need to handle self-signed certificates\n const fetchOptions: any = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: token.refreshToken,\n client_id: clientId,\n client_secret: clientSecret,\n }),\n };\n \n // Add agent for self-signed certificates in development\n if (process.env.NODE_ENV !== 'production' && tokenUrl.startsWith('https://')) {\n const https = await import('https');\n fetchOptions.agent = new https.Agent({\n rejectUnauthorized: false\n });\n }\n \n const response = await fetch(tokenUrl, fetchOptions);\n const refreshedTokens = await response.json();\n \n if (!response.ok) {\n throw refreshedTokens;\n }\n \n return {\n ...token,\n accessToken: refreshedTokens.access_token,\n refreshToken: refreshedTokens.refresh_token ?? token.refreshToken,\n // Store expiration time in seconds (Unix timestamp)\n expiresAt: Math.floor(Date.now() / 1000) + (refreshedTokens.expires_in || 3600),\n // Explicitly remove any error property on successful refresh\n error: undefined,\n };\n } catch (error) {\n console.error('Failed to refresh access token:', error);\n return {\n ...token,\n error: 'RefreshAccessTokenError',\n };\n }\n}","import type { OAuthConfig, OAuthUserConfig } from 'next-auth/providers/oauth';\n\nexport interface OAuth42Profile {\n sub: string;\n email: string;\n email_verified?: boolean;\n name?: string;\n given_name?: string;\n family_name?: string;\n picture?: string;\n username?: string;\n id?: string;\n}\n\nexport interface OAuth42ProviderOptions {\n clientId: string;\n clientSecret: string;\n issuer?: string;\n authorizationUrl?: string;\n tokenUrl?: string;\n userinfoUrl?: string;\n scopes?: string[];\n pkceEnabled?: boolean;\n}\n\nexport function OAuth42Provider<P extends OAuth42Profile>(\n options: OAuthUserConfig<P> & Partial<OAuth42ProviderOptions>\n): OAuthConfig<P> {\n const issuer = options.issuer || process.env.OAUTH42_ISSUER || 'https://oauth42.com';\n const baseUrl = issuer.replace(/\\/$/, '');\n \n return {\n id: 'oauth42',\n name: 'OAuth42',\n type: 'oauth',\n version: '2.0',\n \n // Use OIDC discovery to automatically find endpoints\n wellKnown: `${baseUrl}/.well-known/openid-configuration`,\n \n // Also set individual endpoints for compatibility\n authorization: {\n url: `${baseUrl}/oauth2/authorize`,\n params: {\n scope: (options.scopes || ['openid', 'profile', 'email']).join(' '),\n response_type: 'code',\n },\n },\n token: `${baseUrl}/oauth2/token`,\n userinfo: `${baseUrl}/oauth2/userinfo`,\n \n client: {\n id: options.clientId,\n secret: options.clientSecret,\n token_endpoint_auth_method: 'client_secret_post',\n id_token_signed_response_alg: 'HS256', // OAuth42 uses HS256 for ID tokens\n },\n \n issuer: baseUrl,\n \n checks: options.pkceEnabled !== false ? ['pkce', 'state'] : ['state'],\n \n profile(profile: OAuth42Profile, tokens: any) {\n return {\n id: profile.sub || profile.id || profile.email,\n email: profile.email,\n emailVerified: profile.email_verified ? new Date() : null,\n name: profile.name || `${profile.given_name || ''} ${profile.family_name || ''}`.trim(),\n image: profile.picture,\n };\n },\n \n style: {\n logo: '/oauth42-logo.svg',\n bg: '#1e40af',\n text: '#ffffff',\n },\n \n options,\n };\n}","import { getServerSession as getNextAuthSession } from 'next-auth';\nimport { NextAuthOptions } from 'next-auth';\nimport { GetServerSidePropsContext, NextApiRequest, NextApiResponse } from 'next';\n\n/**\n * Get the OAuth42 session server-side\n * \n * This is the primary method for retrieving sessions in OAuth42 SDK.\n * Supports both Pages Router and App Router:\n * \n * App Router:\n * ```ts\n * const session = await getOAuth42Session(authOptions);\n * ```\n * \n * Pages Router:\n * ```ts\n * const session = await getOAuth42Session(req, res, authOptions);\n * ```\n */\nexport async function getOAuth42Session(\n ...args: \n | [GetServerSidePropsContext['req'], GetServerSidePropsContext['res'], NextAuthOptions]\n | [NextApiRequest, NextApiResponse, NextAuthOptions]\n | [NextAuthOptions]\n) {\n return getNextAuthSession(...args as any);\n}\n\n/**\n * Helper for protecting API routes\n */\nexport function withOAuth42Session(\n handler: (req: NextApiRequest, res: NextApiResponse, session: any) => Promise<void> | void,\n authOptions: NextAuthOptions\n) {\n return async (req: NextApiRequest, res: NextApiResponse) => {\n const session = await getOAuth42Session(req, res, authOptions);\n \n if (!session) {\n return res.status(401).json({ error: 'Unauthorized' });\n }\n \n return handler(req, res, session);\n };\n}\n\n/**\n * Helper for protecting server-side props\n */\nexport function withOAuth42ServerSideProps(\n getServerSideProps: (\n context: GetServerSidePropsContext,\n session: any\n ) => Promise<any>,\n authOptions: NextAuthOptions\n) {\n return async (context: GetServerSidePropsContext) => {\n const session = await getOAuth42Session(\n context.req,\n context.res,\n authOptions\n );\n \n if (!session) {\n return {\n redirect: {\n destination: '/auth/signin',\n permanent: false,\n },\n };\n }\n \n return getServerSideProps(context, session);\n };\n}","import { NextRequest, NextResponse } from 'next/server';\nimport { getToken } from 'next-auth/jwt';\n\nexport interface OAuth42AuthOptions {\n pages?: {\n signIn?: string;\n error?: string;\n };\n callbacks?: {\n authorized?: (params: { token: any; req: NextRequest }) => boolean | Promise<boolean>;\n };\n protectedPaths?: string[];\n publicPaths?: string[];\n}\n\n/**\n * Middleware helper for protecting routes with OAuth42\n */\nexport function withOAuth42Auth(options: OAuth42AuthOptions = {}) {\n return async function middleware(req: NextRequest) {\n const token = await getToken({ \n req: req as any, \n secret: process.env.NEXTAUTH_SECRET \n });\n \n const pathname = req.nextUrl.pathname;\n \n // Check if path is explicitly public\n if (options.publicPaths?.some(path => pathname.startsWith(path))) {\n return NextResponse.next();\n }\n \n // Check if path needs protection\n const needsProtection = options.protectedPaths\n ? options.protectedPaths.some(path => pathname.startsWith(path))\n : true; // Default to protecting all paths\n \n if (!needsProtection) {\n return NextResponse.next();\n }\n \n // Check authorization\n let isAuthorized = !!token;\n \n if (options.callbacks?.authorized) {\n isAuthorized = await options.callbacks.authorized({ token, req });\n }\n \n if (!isAuthorized) {\n const signInUrl = options.pages?.signIn || '/auth/signin';\n const url = new URL(signInUrl, req.url);\n url.searchParams.set('callbackUrl', pathname);\n return NextResponse.redirect(url);\n }\n \n return NextResponse.next();\n };\n}\n\n/**\n * Helper to create middleware configuration\n */\nexport function createMiddlewareConfig(\n protectedPaths: string[] = ['/protected'],\n publicPaths: string[] = ['/auth', '/api/auth']\n) {\n return {\n matcher: [\n /*\n * Match all request paths except for the ones starting with:\n * - _next/static (static files)\n * - _next/image (image optimization files)\n * - favicon.ico (favicon file)\n * - public folder\n */\n '/((?!_next/static|_next/image|favicon.ico|public).*)',\n ],\n protectedPaths,\n publicPaths,\n };\n}"],"mappings":"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","names":["import_next_auth","getNextAuthSession","NextAuthDefault","import_next_auth"]}