@sonicjs-cms/core 2.10.0 → 2.11.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-CJYFSKH7.js → chunk-2MXF4RYZ.js} +3 -3
- package/dist/{chunk-CJYFSKH7.js.map → chunk-2MXF4RYZ.js.map} +1 -1
- package/dist/{chunk-MNFY6DWY.cjs → chunk-56GUBLJE.cjs} +7 -7
- package/dist/{chunk-MNFY6DWY.cjs.map → chunk-56GUBLJE.cjs.map} +1 -1
- package/dist/{chunk-IIBRG5S5.cjs → chunk-6BVLPACH.cjs} +408 -2
- package/dist/chunk-6BVLPACH.cjs.map +1 -0
- package/dist/{chunk-RCA6R6VE.cjs → chunk-ASAEJ4B7.cjs} +315 -162
- package/dist/chunk-ASAEJ4B7.cjs.map +1 -0
- package/dist/{chunk-IT2TC4ZD.cjs → chunk-B2ASV5RD.cjs} +13 -7
- package/dist/chunk-B2ASV5RD.cjs.map +1 -0
- package/dist/{chunk-IZWNIUJI.js → chunk-BUU2US2Z.js} +3 -3
- package/dist/{chunk-IZWNIUJI.js.map → chunk-BUU2US2Z.js.map} +1 -1
- package/dist/{chunk-ZMVWMJ3S.cjs → chunk-DE5YTNCD.cjs} +9 -2
- package/dist/chunk-DE5YTNCD.cjs.map +1 -0
- package/dist/{chunk-4TTMQQC7.js → chunk-GKRGDJGG.js} +10 -4
- package/dist/chunk-GKRGDJGG.js.map +1 -0
- package/dist/{chunk-6O3RJV3C.js → chunk-H55AYIRI.js} +9 -2
- package/dist/chunk-H55AYIRI.js.map +1 -0
- package/dist/{chunk-JTNUM7JE.js → chunk-JTQBNSZX.js} +187 -34
- package/dist/chunk-JTQBNSZX.js.map +1 -0
- package/dist/{chunk-64APW3DW.cjs → chunk-LFAQUR7P.cjs} +9 -2
- package/dist/chunk-LFAQUR7P.cjs.map +1 -0
- package/dist/{chunk-27AOVQTR.js → chunk-NMLFKXWW.js} +402 -3
- package/dist/chunk-NMLFKXWW.js.map +1 -0
- package/dist/{chunk-EKPLKUZT.cjs → chunk-QLPFENZ2.cjs} +3 -3
- package/dist/{chunk-EKPLKUZT.cjs.map → chunk-QLPFENZ2.cjs.map} +1 -1
- package/dist/{chunk-KYGRJCZM.cjs → chunk-QTFKZBLC.cjs} +3 -2
- package/dist/chunk-QTFKZBLC.cjs.map +1 -0
- package/dist/{chunk-LOUJRBXV.js → chunk-QXOZI5Q2.js} +3 -2
- package/dist/chunk-QXOZI5Q2.js.map +1 -0
- package/dist/{chunk-7JMMLHPQ.js → chunk-VJCLJH3X.js} +9 -2
- package/dist/chunk-VJCLJH3X.js.map +1 -0
- package/dist/index.cjs +751 -152
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +125 -5
- package/dist/index.d.ts +125 -5
- package/dist/index.js +582 -15
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +29 -29
- package/dist/middleware.js +3 -3
- package/dist/migrations-UFVJTPVT.js +4 -0
- package/dist/{migrations-N2C2VPJU.js.map → migrations-UFVJTPVT.js.map} +1 -1
- package/dist/migrations-VNYOSUNE.cjs +13 -0
- package/dist/{migrations-ONIAY6GK.cjs.map → migrations-VNYOSUNE.cjs.map} +1 -1
- package/dist/{plugin-0Xogrln-.d.cts → plugin-DDYetMF-.d.cts} +1 -0
- package/dist/{plugin-0Xogrln-.d.ts → plugin-DDYetMF-.d.ts} +1 -0
- package/dist/{plugin-bootstrap-fpG98Otb.d.cts → plugin-bootstrap-DCXpeQVb.d.cts} +229 -1
- package/dist/{plugin-bootstrap-WmpvYM5w.d.ts → plugin-bootstrap-DXBAYaqM.d.ts} +229 -1
- package/dist/{plugin-manager-GcIeb226.d.cts → plugin-manager-BoM3Q7o7.d.cts} +1 -1
- package/dist/{plugin-manager-Clf2gXwj.d.ts → plugin-manager-Efx9RyDX.d.ts} +1 -1
- package/dist/plugins.cjs +10 -10
- package/dist/plugins.d.cts +2 -2
- package/dist/plugins.d.ts +2 -2
- package/dist/plugins.js +2 -2
- package/dist/routes.cjs +29 -29
- package/dist/routes.js +6 -6
- package/dist/services.cjs +60 -32
- package/dist/services.d.cts +1 -1
- package/dist/services.d.ts +1 -1
- package/dist/services.js +3 -3
- package/dist/types.cjs +2 -2
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utils.cjs +11 -11
- package/dist/utils.js +1 -1
- package/migrations/033_form_content_integration.sql +19 -0
- package/package.json +1 -1
- package/dist/chunk-27AOVQTR.js.map +0 -1
- package/dist/chunk-4TTMQQC7.js.map +0 -1
- package/dist/chunk-64APW3DW.cjs.map +0 -1
- package/dist/chunk-6O3RJV3C.js.map +0 -1
- package/dist/chunk-7JMMLHPQ.js.map +0 -1
- package/dist/chunk-IIBRG5S5.cjs.map +0 -1
- package/dist/chunk-IT2TC4ZD.cjs.map +0 -1
- package/dist/chunk-JTNUM7JE.js.map +0 -1
- package/dist/chunk-KYGRJCZM.cjs.map +0 -1
- package/dist/chunk-LOUJRBXV.js.map +0 -1
- package/dist/chunk-RCA6R6VE.cjs.map +0 -1
- package/dist/chunk-ZMVWMJ3S.cjs.map +0 -1
- package/dist/migrations-N2C2VPJU.js +0 -4
- package/dist/migrations-ONIAY6GK.cjs +0 -13
package/dist/index.js
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
import { renderConfirmationDialog, getConfirmationDialogScript, api_default, api_media_default, api_system_default, admin_api_default, router, adminCollectionsRoutes, adminFormsRoutes, adminSettingsRoutes, public_forms_default, router2, admin_content_default, adminMediaRoutes, adminPluginRoutes, adminLogsRoutes, userRoutes, auth_default, test_cleanup_default } from './chunk-
|
|
2
|
-
export { ROUTES_INFO, admin_api_default as adminApiRoutes, adminCheckboxRoutes, admin_code_examples_default as adminCodeExamplesRoutes, adminCollectionsRoutes, admin_content_default as adminContentRoutes, router as adminDashboardRoutes, adminDesignRoutes, adminLogsRoutes, adminMediaRoutes, adminPluginRoutes, adminSettingsRoutes, admin_testimonials_default as adminTestimonialsRoutes, userRoutes as adminUsersRoutes, api_content_crud_default as apiContentCrudRoutes, api_media_default as apiMediaRoutes, api_default as apiRoutes, api_system_default as apiSystemRoutes, auth_default as authRoutes } from './chunk-
|
|
3
|
-
import { SettingsService, setAppInstance, schema_exports } from './chunk-
|
|
4
|
-
export { Logger, apiTokens, collections, content, contentVersions, getLogger, initLogger, insertCollectionSchema, insertContentSchema, insertLogConfigSchema, insertMediaSchema, insertPluginActivityLogSchema, insertPluginAssetSchema, insertPluginHookSchema, insertPluginRouteSchema, insertPluginSchema, insertSystemLogSchema, insertUserSchema, insertWorkflowHistorySchema, logConfig, media, pluginActivityLog, pluginAssets, pluginHooks, pluginRoutes, plugins, selectCollectionSchema, selectContentSchema, selectLogConfigSchema, selectMediaSchema, selectPluginActivityLogSchema, selectPluginAssetSchema, selectPluginHookSchema, selectPluginRouteSchema, selectPluginSchema, selectSystemLogSchema, selectUserSchema, selectWorkflowHistorySchema, systemLogs, users, workflowHistory } from './chunk-
|
|
5
|
-
import { requireAuth, AuthManager, metricsMiddleware, bootstrapMiddleware, securityHeadersMiddleware, csrfProtection } from './chunk-
|
|
6
|
-
export { AuthManager, PermissionManager, bootstrapMiddleware, cacheHeaders, compressionMiddleware, detailedLoggingMiddleware, getActivePlugins, isPluginActive, logActivity, loggingMiddleware, optionalAuth, performanceLoggingMiddleware, requireActivePlugin, requireActivePlugins, requireAnyPermission, requireAuth, requirePermission, requireRole, securityHeadersMiddleware as securityHeaders, securityLoggingMiddleware } from './chunk-
|
|
7
|
-
export { PluginBootstrapService, PluginService as PluginServiceClass, cleanupRemovedCollections, fullCollectionSync, getAvailableCollectionNames, getManagedCollections, isCollectionManaged, loadCollectionConfig, loadCollectionConfigs, registerCollections, syncCollection, syncCollections, validateCollectionConfig } from './chunk-
|
|
8
|
-
export { MigrationService } from './chunk-
|
|
1
|
+
import { renderConfirmationDialog, getConfirmationDialogScript, api_default, api_media_default, api_system_default, admin_api_default, router, adminCollectionsRoutes, adminFormsRoutes, adminSettingsRoutes, public_forms_default, router2, admin_content_default, adminMediaRoutes, adminPluginRoutes, adminLogsRoutes, userRoutes, auth_default, test_cleanup_default } from './chunk-JTQBNSZX.js';
|
|
2
|
+
export { ROUTES_INFO, admin_api_default as adminApiRoutes, adminCheckboxRoutes, admin_code_examples_default as adminCodeExamplesRoutes, adminCollectionsRoutes, admin_content_default as adminContentRoutes, router as adminDashboardRoutes, adminDesignRoutes, adminLogsRoutes, adminMediaRoutes, adminPluginRoutes, adminSettingsRoutes, admin_testimonials_default as adminTestimonialsRoutes, userRoutes as adminUsersRoutes, api_content_crud_default as apiContentCrudRoutes, api_media_default as apiMediaRoutes, api_default as apiRoutes, api_system_default as apiSystemRoutes, auth_default as authRoutes } from './chunk-JTQBNSZX.js';
|
|
3
|
+
import { SettingsService, setAppInstance, schema_exports } from './chunk-VJCLJH3X.js';
|
|
4
|
+
export { Logger, apiTokens, collections, content, contentVersions, getLogger, initLogger, insertCollectionSchema, insertContentSchema, insertLogConfigSchema, insertMediaSchema, insertPluginActivityLogSchema, insertPluginAssetSchema, insertPluginHookSchema, insertPluginRouteSchema, insertPluginSchema, insertSystemLogSchema, insertUserSchema, insertWorkflowHistorySchema, logConfig, media, pluginActivityLog, pluginAssets, pluginHooks, pluginRoutes, plugins, selectCollectionSchema, selectContentSchema, selectLogConfigSchema, selectMediaSchema, selectPluginActivityLogSchema, selectPluginAssetSchema, selectPluginHookSchema, selectPluginRouteSchema, selectPluginSchema, selectSystemLogSchema, selectUserSchema, selectWorkflowHistorySchema, systemLogs, users, workflowHistory } from './chunk-VJCLJH3X.js';
|
|
5
|
+
import { requireAuth, AuthManager, metricsMiddleware, bootstrapMiddleware, securityHeadersMiddleware, csrfProtection } from './chunk-GKRGDJGG.js';
|
|
6
|
+
export { AuthManager, PermissionManager, bootstrapMiddleware, cacheHeaders, compressionMiddleware, detailedLoggingMiddleware, getActivePlugins, isPluginActive, logActivity, loggingMiddleware, optionalAuth, performanceLoggingMiddleware, requireActivePlugin, requireActivePlugins, requireAnyPermission, requireAuth, requirePermission, requireRole, securityHeadersMiddleware as securityHeaders, securityLoggingMiddleware } from './chunk-GKRGDJGG.js';
|
|
7
|
+
export { PluginBootstrapService, PluginService as PluginServiceClass, backfillFormSubmissions, cleanupRemovedCollections, createContentFromSubmission, deriveCollectionSchemaFromFormio, deriveSubmissionTitle, fullCollectionSync, getAvailableCollectionNames, getManagedCollections, isCollectionManaged, loadCollectionConfig, loadCollectionConfigs, mapFormStatusToContentStatus, registerCollections, syncAllFormCollections, syncCollection, syncCollections, syncFormCollection, validateCollectionConfig } from './chunk-NMLFKXWW.js';
|
|
8
|
+
export { MigrationService } from './chunk-H55AYIRI.js';
|
|
9
9
|
export { renderFilterBar } from './chunk-74XCYEI7.js';
|
|
10
10
|
import { init_admin_layout_catalyst_template, renderAdminLayout, renderAdminLayoutCatalyst } from './chunk-JJS7JZCH.js';
|
|
11
11
|
export { getConfirmationDialogScript, renderAlert, renderConfirmationDialog, renderForm, renderFormField, renderPagination, renderTable } from './chunk-JJS7JZCH.js';
|
|
12
|
-
export { HookSystemImpl, HookUtils, PluginManager as PluginManagerClass, PluginRegistryImpl, PluginValidator as PluginValidatorClass, ScopedHookSystem as ScopedHookSystemClass } from './chunk-
|
|
12
|
+
export { HookSystemImpl, HookUtils, PluginManager as PluginManagerClass, PluginRegistryImpl, PluginValidator as PluginValidatorClass, ScopedHookSystem as ScopedHookSystemClass } from './chunk-2MXF4RYZ.js';
|
|
13
13
|
import { PluginBuilder } from './chunk-J5WGMRSU.js';
|
|
14
14
|
export { PluginBuilder, PluginHelpers } from './chunk-J5WGMRSU.js';
|
|
15
|
-
import { package_default, getCoreVersion } from './chunk-
|
|
16
|
-
export { QueryFilterBuilder, SONICJS_VERSION, TemplateRenderer, buildQuery, getCoreVersion, renderTemplate, templateRenderer } from './chunk-
|
|
15
|
+
import { package_default, getCoreVersion } from './chunk-BUU2US2Z.js';
|
|
16
|
+
export { QueryFilterBuilder, SONICJS_VERSION, TemplateRenderer, buildQuery, getCoreVersion, renderTemplate, templateRenderer } from './chunk-BUU2US2Z.js';
|
|
17
17
|
import './chunk-X7ZAEI5S.js';
|
|
18
18
|
export { metricsTracker } from './chunk-FICTAGD4.js';
|
|
19
19
|
export { escapeHtml, sanitizeInput, sanitizeObject } from './chunk-TQABQWOP.js';
|
|
20
|
-
export { HOOKS } from './chunk-
|
|
20
|
+
export { HOOKS } from './chunk-QXOZI5Q2.js';
|
|
21
21
|
import './chunk-V4OQ3NZ2.js';
|
|
22
22
|
import { Hono } from 'hono';
|
|
23
|
-
import { setCookie } from 'hono/cookie';
|
|
23
|
+
import { setCookie, getCookie } from 'hono/cookie';
|
|
24
24
|
import { z } from 'zod';
|
|
25
25
|
import { drizzle } from 'drizzle-orm/d1';
|
|
26
26
|
|
|
@@ -1826,7 +1826,8 @@ function createOTPLoginPlugin() {
|
|
|
1826
1826
|
email: normalizedEmail,
|
|
1827
1827
|
ipAddress,
|
|
1828
1828
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1829
|
-
appName: siteName
|
|
1829
|
+
appName: siteName,
|
|
1830
|
+
logoUrl: settings.logoUrl || ""
|
|
1830
1831
|
});
|
|
1831
1832
|
const emailPlugin2 = await db.prepare(`
|
|
1832
1833
|
SELECT settings FROM plugins WHERE id = 'email'
|
|
@@ -2001,6 +2002,567 @@ function createOTPLoginPlugin() {
|
|
|
2001
2002
|
}
|
|
2002
2003
|
var otpLoginPlugin = createOTPLoginPlugin();
|
|
2003
2004
|
|
|
2005
|
+
// src/plugins/core-plugins/oauth-providers/oauth-service.ts
|
|
2006
|
+
var GITHUB_PROVIDER = {
|
|
2007
|
+
id: "github",
|
|
2008
|
+
name: "GitHub",
|
|
2009
|
+
authorizeUrl: "https://github.com/login/oauth/authorize",
|
|
2010
|
+
tokenUrl: "https://github.com/login/oauth/access_token",
|
|
2011
|
+
userInfoUrl: "https://api.github.com/user",
|
|
2012
|
+
scopes: ["read:user", "user:email"],
|
|
2013
|
+
mapProfile: (profile) => ({
|
|
2014
|
+
providerAccountId: String(profile.id),
|
|
2015
|
+
email: profile.email || "",
|
|
2016
|
+
name: profile.name || profile.login || "",
|
|
2017
|
+
avatar: profile.avatar_url || void 0
|
|
2018
|
+
})
|
|
2019
|
+
};
|
|
2020
|
+
var GOOGLE_PROVIDER = {
|
|
2021
|
+
id: "google",
|
|
2022
|
+
name: "Google",
|
|
2023
|
+
authorizeUrl: "https://accounts.google.com/o/oauth2/v2/auth",
|
|
2024
|
+
tokenUrl: "https://oauth2.googleapis.com/token",
|
|
2025
|
+
userInfoUrl: "https://www.googleapis.com/oauth2/v2/userinfo",
|
|
2026
|
+
scopes: ["openid", "email", "profile"],
|
|
2027
|
+
mapProfile: (profile) => ({
|
|
2028
|
+
providerAccountId: String(profile.id),
|
|
2029
|
+
email: profile.email || "",
|
|
2030
|
+
name: profile.name || "",
|
|
2031
|
+
avatar: profile.picture || void 0
|
|
2032
|
+
})
|
|
2033
|
+
};
|
|
2034
|
+
var BUILT_IN_PROVIDERS = {
|
|
2035
|
+
github: GITHUB_PROVIDER,
|
|
2036
|
+
google: GOOGLE_PROVIDER
|
|
2037
|
+
};
|
|
2038
|
+
var OAuthService = class {
|
|
2039
|
+
constructor(db) {
|
|
2040
|
+
this.db = db;
|
|
2041
|
+
}
|
|
2042
|
+
/**
|
|
2043
|
+
* Build the authorization redirect URL for a provider.
|
|
2044
|
+
*/
|
|
2045
|
+
buildAuthorizeUrl(provider, clientId, redirectUri, state) {
|
|
2046
|
+
const params = new URLSearchParams({
|
|
2047
|
+
client_id: clientId,
|
|
2048
|
+
redirect_uri: redirectUri,
|
|
2049
|
+
response_type: "code",
|
|
2050
|
+
scope: provider.scopes.join(" "),
|
|
2051
|
+
state
|
|
2052
|
+
});
|
|
2053
|
+
if (provider.id === "google") {
|
|
2054
|
+
params.set("access_type", "offline");
|
|
2055
|
+
params.set("prompt", "consent");
|
|
2056
|
+
}
|
|
2057
|
+
return `${provider.authorizeUrl}?${params.toString()}`;
|
|
2058
|
+
}
|
|
2059
|
+
/**
|
|
2060
|
+
* Exchange authorization code for tokens using native fetch.
|
|
2061
|
+
*/
|
|
2062
|
+
async exchangeCode(provider, clientId, clientSecret, code, redirectUri) {
|
|
2063
|
+
const body = {
|
|
2064
|
+
client_id: clientId,
|
|
2065
|
+
client_secret: clientSecret,
|
|
2066
|
+
code,
|
|
2067
|
+
redirect_uri: redirectUri,
|
|
2068
|
+
grant_type: "authorization_code"
|
|
2069
|
+
};
|
|
2070
|
+
const response = await fetch(provider.tokenUrl, {
|
|
2071
|
+
method: "POST",
|
|
2072
|
+
headers: {
|
|
2073
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
2074
|
+
"Accept": "application/json"
|
|
2075
|
+
},
|
|
2076
|
+
body: new URLSearchParams(body).toString()
|
|
2077
|
+
});
|
|
2078
|
+
if (!response.ok) {
|
|
2079
|
+
const errorText = await response.text();
|
|
2080
|
+
throw new Error(`Token exchange failed (${response.status}): ${errorText}`);
|
|
2081
|
+
}
|
|
2082
|
+
const data = await response.json();
|
|
2083
|
+
if (data.error) {
|
|
2084
|
+
throw new Error(`Token exchange error: ${data.error_description || data.error}`);
|
|
2085
|
+
}
|
|
2086
|
+
return {
|
|
2087
|
+
access_token: data.access_token,
|
|
2088
|
+
refresh_token: data.refresh_token,
|
|
2089
|
+
expires_in: data.expires_in ? Number(data.expires_in) : void 0
|
|
2090
|
+
};
|
|
2091
|
+
}
|
|
2092
|
+
/**
|
|
2093
|
+
* Fetch user profile from the provider's userinfo endpoint.
|
|
2094
|
+
*/
|
|
2095
|
+
async fetchUserProfile(provider, accessToken) {
|
|
2096
|
+
const headers = {
|
|
2097
|
+
"Authorization": `Bearer ${accessToken}`,
|
|
2098
|
+
"Accept": "application/json"
|
|
2099
|
+
};
|
|
2100
|
+
if (provider.id === "github") {
|
|
2101
|
+
headers["Authorization"] = `token ${accessToken}`;
|
|
2102
|
+
}
|
|
2103
|
+
const response = await fetch(provider.userInfoUrl, { headers });
|
|
2104
|
+
if (!response.ok) {
|
|
2105
|
+
throw new Error(`Failed to fetch user profile (${response.status})`);
|
|
2106
|
+
}
|
|
2107
|
+
const profile = await response.json();
|
|
2108
|
+
if (provider.id === "github" && !profile.email) {
|
|
2109
|
+
const emailResponse = await fetch("https://api.github.com/user/emails", {
|
|
2110
|
+
headers: {
|
|
2111
|
+
"Authorization": `token ${accessToken}`,
|
|
2112
|
+
"Accept": "application/json"
|
|
2113
|
+
}
|
|
2114
|
+
});
|
|
2115
|
+
if (emailResponse.ok) {
|
|
2116
|
+
const emails = await emailResponse.json();
|
|
2117
|
+
const primaryEmail = emails.find((e) => e.primary && e.verified);
|
|
2118
|
+
if (primaryEmail) {
|
|
2119
|
+
profile.email = primaryEmail.email;
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
return provider.mapProfile(profile);
|
|
2124
|
+
}
|
|
2125
|
+
// ─── Database Operations ────────────────────────────────────────────────
|
|
2126
|
+
/**
|
|
2127
|
+
* Find an existing OAuth account link.
|
|
2128
|
+
*/
|
|
2129
|
+
async findOAuthAccount(provider, providerAccountId) {
|
|
2130
|
+
return await this.db.prepare(`
|
|
2131
|
+
SELECT * FROM oauth_accounts
|
|
2132
|
+
WHERE provider = ? AND provider_account_id = ?
|
|
2133
|
+
`).bind(provider, providerAccountId).first();
|
|
2134
|
+
}
|
|
2135
|
+
/**
|
|
2136
|
+
* Find all OAuth accounts for a user.
|
|
2137
|
+
*/
|
|
2138
|
+
async findUserOAuthAccounts(userId) {
|
|
2139
|
+
const result = await this.db.prepare(`
|
|
2140
|
+
SELECT * FROM oauth_accounts WHERE user_id = ?
|
|
2141
|
+
`).bind(userId).all();
|
|
2142
|
+
return result.results || [];
|
|
2143
|
+
}
|
|
2144
|
+
/**
|
|
2145
|
+
* Create a new OAuth account link.
|
|
2146
|
+
*/
|
|
2147
|
+
async createOAuthAccount(params) {
|
|
2148
|
+
const id = crypto.randomUUID();
|
|
2149
|
+
const now = Date.now();
|
|
2150
|
+
await this.db.prepare(`
|
|
2151
|
+
INSERT INTO oauth_accounts (
|
|
2152
|
+
id, user_id, provider, provider_account_id,
|
|
2153
|
+
access_token, refresh_token, token_expires_at,
|
|
2154
|
+
profile_data, created_at, updated_at
|
|
2155
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
2156
|
+
`).bind(
|
|
2157
|
+
id,
|
|
2158
|
+
params.userId,
|
|
2159
|
+
params.provider,
|
|
2160
|
+
params.providerAccountId,
|
|
2161
|
+
params.accessToken,
|
|
2162
|
+
params.refreshToken || null,
|
|
2163
|
+
params.tokenExpiresAt || null,
|
|
2164
|
+
params.profileData || null,
|
|
2165
|
+
now,
|
|
2166
|
+
now
|
|
2167
|
+
).run();
|
|
2168
|
+
return {
|
|
2169
|
+
id,
|
|
2170
|
+
user_id: params.userId,
|
|
2171
|
+
provider: params.provider,
|
|
2172
|
+
provider_account_id: params.providerAccountId,
|
|
2173
|
+
access_token: params.accessToken,
|
|
2174
|
+
refresh_token: params.refreshToken || null,
|
|
2175
|
+
token_expires_at: params.tokenExpiresAt || null,
|
|
2176
|
+
profile_data: params.profileData || null,
|
|
2177
|
+
created_at: now,
|
|
2178
|
+
updated_at: now
|
|
2179
|
+
};
|
|
2180
|
+
}
|
|
2181
|
+
/**
|
|
2182
|
+
* Update tokens for an existing OAuth account.
|
|
2183
|
+
*/
|
|
2184
|
+
async updateOAuthTokens(id, accessToken, refreshToken, tokenExpiresAt) {
|
|
2185
|
+
await this.db.prepare(`
|
|
2186
|
+
UPDATE oauth_accounts
|
|
2187
|
+
SET access_token = ?, refresh_token = ?, token_expires_at = ?, updated_at = ?
|
|
2188
|
+
WHERE id = ?
|
|
2189
|
+
`).bind(accessToken, refreshToken || null, tokenExpiresAt || null, Date.now(), id).run();
|
|
2190
|
+
}
|
|
2191
|
+
/**
|
|
2192
|
+
* Unlink an OAuth account from a user (only if they have another auth method).
|
|
2193
|
+
*/
|
|
2194
|
+
async unlinkOAuthAccount(userId, provider) {
|
|
2195
|
+
const user = await this.db.prepare(`
|
|
2196
|
+
SELECT password_hash FROM users WHERE id = ?
|
|
2197
|
+
`).bind(userId).first();
|
|
2198
|
+
const otherLinks = await this.db.prepare(`
|
|
2199
|
+
SELECT COUNT(*) as count FROM oauth_accounts
|
|
2200
|
+
WHERE user_id = ? AND provider != ?
|
|
2201
|
+
`).bind(userId, provider).first();
|
|
2202
|
+
const hasPassword = !!user?.password_hash;
|
|
2203
|
+
const hasOtherLinks = (otherLinks?.count || 0) > 0;
|
|
2204
|
+
if (!hasPassword && !hasOtherLinks) {
|
|
2205
|
+
return false;
|
|
2206
|
+
}
|
|
2207
|
+
await this.db.prepare(`
|
|
2208
|
+
DELETE FROM oauth_accounts WHERE user_id = ? AND provider = ?
|
|
2209
|
+
`).bind(userId, provider).run();
|
|
2210
|
+
return true;
|
|
2211
|
+
}
|
|
2212
|
+
/**
|
|
2213
|
+
* Find a user by email.
|
|
2214
|
+
*/
|
|
2215
|
+
async findUserByEmail(email) {
|
|
2216
|
+
return await this.db.prepare(`
|
|
2217
|
+
SELECT id, email, role, is_active, first_name, last_name
|
|
2218
|
+
FROM users WHERE email = ?
|
|
2219
|
+
`).bind(email.toLowerCase()).first();
|
|
2220
|
+
}
|
|
2221
|
+
/**
|
|
2222
|
+
* Create a new user from an OAuth profile.
|
|
2223
|
+
*/
|
|
2224
|
+
async createUserFromOAuth(profile) {
|
|
2225
|
+
const id = crypto.randomUUID();
|
|
2226
|
+
const now = Date.now();
|
|
2227
|
+
const email = profile.email.toLowerCase();
|
|
2228
|
+
const nameParts = (profile.name || email.split("@")[0] || "User").split(" ");
|
|
2229
|
+
const firstName = nameParts[0] || "User";
|
|
2230
|
+
const lastName = nameParts.slice(1).join(" ") || "";
|
|
2231
|
+
const username = email.split("@")[0] || id.substring(0, 8);
|
|
2232
|
+
const existing = await this.db.prepare(
|
|
2233
|
+
"SELECT id FROM users WHERE username = ?"
|
|
2234
|
+
).bind(username).first();
|
|
2235
|
+
const finalUsername = existing ? `${username}-${id.substring(0, 6)}` : username;
|
|
2236
|
+
await this.db.prepare(`
|
|
2237
|
+
INSERT INTO users (
|
|
2238
|
+
id, email, username, first_name, last_name,
|
|
2239
|
+
password_hash, role, avatar, is_active, created_at, updated_at
|
|
2240
|
+
) VALUES (?, ?, ?, ?, ?, NULL, 'viewer', ?, 1, ?, ?)
|
|
2241
|
+
`).bind(
|
|
2242
|
+
id,
|
|
2243
|
+
email,
|
|
2244
|
+
finalUsername,
|
|
2245
|
+
firstName,
|
|
2246
|
+
lastName,
|
|
2247
|
+
profile.avatar || null,
|
|
2248
|
+
now,
|
|
2249
|
+
now
|
|
2250
|
+
).run();
|
|
2251
|
+
return id;
|
|
2252
|
+
}
|
|
2253
|
+
/**
|
|
2254
|
+
* Generate a cryptographically random state parameter for CSRF protection.
|
|
2255
|
+
*/
|
|
2256
|
+
generateState() {
|
|
2257
|
+
const bytes = new Uint8Array(32);
|
|
2258
|
+
crypto.getRandomValues(bytes);
|
|
2259
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
2260
|
+
}
|
|
2261
|
+
};
|
|
2262
|
+
|
|
2263
|
+
// src/plugins/core-plugins/oauth-providers/index.ts
|
|
2264
|
+
var STATE_COOKIE_NAME = "oauth_state";
|
|
2265
|
+
var STATE_COOKIE_MAX_AGE = 600;
|
|
2266
|
+
function createOAuthProvidersPlugin() {
|
|
2267
|
+
const builder = PluginBuilder.create({
|
|
2268
|
+
name: "oauth-providers",
|
|
2269
|
+
version: "1.0.0-beta.1",
|
|
2270
|
+
description: "OAuth2/OIDC social login with GitHub, Google, and more"
|
|
2271
|
+
});
|
|
2272
|
+
builder.metadata({
|
|
2273
|
+
author: {
|
|
2274
|
+
name: "SonicJS Team",
|
|
2275
|
+
email: "team@sonicjs.com"
|
|
2276
|
+
},
|
|
2277
|
+
license: "MIT",
|
|
2278
|
+
compatibility: "^2.0.0"
|
|
2279
|
+
});
|
|
2280
|
+
function getCallbackUrl(c, provider) {
|
|
2281
|
+
const proto = c.req.header("x-forwarded-proto") || "https";
|
|
2282
|
+
const host = c.req.header("host") || "localhost";
|
|
2283
|
+
return `${proto}://${host}/auth/oauth/${provider}/callback`;
|
|
2284
|
+
}
|
|
2285
|
+
async function loadSettings(db) {
|
|
2286
|
+
const row = await db.prepare(
|
|
2287
|
+
`SELECT settings FROM plugins WHERE id = 'oauth-providers'`
|
|
2288
|
+
).first();
|
|
2289
|
+
if (!row?.settings) return null;
|
|
2290
|
+
try {
|
|
2291
|
+
return JSON.parse(row.settings);
|
|
2292
|
+
} catch {
|
|
2293
|
+
return null;
|
|
2294
|
+
}
|
|
2295
|
+
}
|
|
2296
|
+
function getProviderCredentials(settings, providerId) {
|
|
2297
|
+
if (!settings?.providers?.[providerId]) return null;
|
|
2298
|
+
const p = settings.providers[providerId];
|
|
2299
|
+
if (!p.enabled || !p.clientId || !p.clientSecret) return null;
|
|
2300
|
+
return { clientId: p.clientId, clientSecret: p.clientSecret };
|
|
2301
|
+
}
|
|
2302
|
+
const oauthAPI = new Hono();
|
|
2303
|
+
oauthAPI.get("/:provider", async (c) => {
|
|
2304
|
+
try {
|
|
2305
|
+
const providerId = c.req.param("provider");
|
|
2306
|
+
const providerConfig = BUILT_IN_PROVIDERS[providerId];
|
|
2307
|
+
if (!providerConfig) {
|
|
2308
|
+
return c.json({ error: `Unknown OAuth provider: ${providerId}` }, 400);
|
|
2309
|
+
}
|
|
2310
|
+
const db = c.env.DB;
|
|
2311
|
+
const settings = await loadSettings(db);
|
|
2312
|
+
const creds = getProviderCredentials(settings, providerId);
|
|
2313
|
+
if (!creds) {
|
|
2314
|
+
return c.json({
|
|
2315
|
+
error: `OAuth provider "${providerId}" is not configured or not enabled`
|
|
2316
|
+
}, 400);
|
|
2317
|
+
}
|
|
2318
|
+
const oauthService = new OAuthService(db);
|
|
2319
|
+
const state = oauthService.generateState();
|
|
2320
|
+
const redirectUri = getCallbackUrl(c, providerId);
|
|
2321
|
+
setCookie(c, STATE_COOKIE_NAME, state, {
|
|
2322
|
+
httpOnly: true,
|
|
2323
|
+
secure: true,
|
|
2324
|
+
sameSite: "Lax",
|
|
2325
|
+
// Lax required for OAuth redirect flow
|
|
2326
|
+
maxAge: STATE_COOKIE_MAX_AGE,
|
|
2327
|
+
path: "/auth/oauth"
|
|
2328
|
+
});
|
|
2329
|
+
const authorizeUrl = oauthService.buildAuthorizeUrl(
|
|
2330
|
+
providerConfig,
|
|
2331
|
+
creds.clientId,
|
|
2332
|
+
redirectUri,
|
|
2333
|
+
state
|
|
2334
|
+
);
|
|
2335
|
+
return c.redirect(authorizeUrl);
|
|
2336
|
+
} catch (error) {
|
|
2337
|
+
console.error("OAuth authorize error:", error);
|
|
2338
|
+
return c.json({ error: "Failed to initiate OAuth flow" }, 500);
|
|
2339
|
+
}
|
|
2340
|
+
});
|
|
2341
|
+
oauthAPI.get("/:provider/callback", async (c) => {
|
|
2342
|
+
try {
|
|
2343
|
+
const providerId = c.req.param("provider");
|
|
2344
|
+
const providerConfig = BUILT_IN_PROVIDERS[providerId];
|
|
2345
|
+
if (!providerConfig) {
|
|
2346
|
+
return c.redirect("/auth/login?error=Unknown OAuth provider");
|
|
2347
|
+
}
|
|
2348
|
+
const stateParam = c.req.query("state");
|
|
2349
|
+
const stateCookie = getCookie(c, STATE_COOKIE_NAME);
|
|
2350
|
+
if (!stateParam || !stateCookie || stateParam !== stateCookie) {
|
|
2351
|
+
return c.redirect("/auth/login?error=Invalid OAuth state. Please try again.");
|
|
2352
|
+
}
|
|
2353
|
+
setCookie(c, STATE_COOKIE_NAME, "", {
|
|
2354
|
+
httpOnly: true,
|
|
2355
|
+
secure: true,
|
|
2356
|
+
sameSite: "Lax",
|
|
2357
|
+
maxAge: 0,
|
|
2358
|
+
path: "/auth/oauth"
|
|
2359
|
+
});
|
|
2360
|
+
const errorParam = c.req.query("error");
|
|
2361
|
+
if (errorParam) {
|
|
2362
|
+
const errorDesc = c.req.query("error_description") || errorParam;
|
|
2363
|
+
return c.redirect(`/auth/login?error=${encodeURIComponent(errorDesc)}`);
|
|
2364
|
+
}
|
|
2365
|
+
const code = c.req.query("code");
|
|
2366
|
+
if (!code) {
|
|
2367
|
+
return c.redirect("/auth/login?error=No authorization code received");
|
|
2368
|
+
}
|
|
2369
|
+
const db = c.env.DB;
|
|
2370
|
+
const settings = await loadSettings(db);
|
|
2371
|
+
const creds = getProviderCredentials(settings, providerId);
|
|
2372
|
+
if (!creds) {
|
|
2373
|
+
return c.redirect("/auth/login?error=OAuth provider not configured");
|
|
2374
|
+
}
|
|
2375
|
+
const oauthService = new OAuthService(db);
|
|
2376
|
+
const redirectUri = getCallbackUrl(c, providerId);
|
|
2377
|
+
const tokens = await oauthService.exchangeCode(
|
|
2378
|
+
providerConfig,
|
|
2379
|
+
creds.clientId,
|
|
2380
|
+
creds.clientSecret,
|
|
2381
|
+
code,
|
|
2382
|
+
redirectUri
|
|
2383
|
+
);
|
|
2384
|
+
const profile = await oauthService.fetchUserProfile(providerConfig, tokens.access_token);
|
|
2385
|
+
if (!profile.email) {
|
|
2386
|
+
return c.redirect("/auth/login?error=Could not retrieve email from OAuth provider. Please ensure your email is public or grant email permission.");
|
|
2387
|
+
}
|
|
2388
|
+
const tokenExpiresAt = tokens.expires_in ? Date.now() + tokens.expires_in * 1e3 : null;
|
|
2389
|
+
const existingOAuth = await oauthService.findOAuthAccount(providerId, profile.providerAccountId);
|
|
2390
|
+
if (existingOAuth) {
|
|
2391
|
+
await oauthService.updateOAuthTokens(
|
|
2392
|
+
existingOAuth.id,
|
|
2393
|
+
tokens.access_token,
|
|
2394
|
+
tokens.refresh_token,
|
|
2395
|
+
tokenExpiresAt ?? void 0
|
|
2396
|
+
);
|
|
2397
|
+
const user = await db.prepare(
|
|
2398
|
+
"SELECT id, email, role, is_active FROM users WHERE id = ?"
|
|
2399
|
+
).bind(existingOAuth.user_id).first();
|
|
2400
|
+
if (!user || !user.is_active) {
|
|
2401
|
+
return c.redirect("/auth/login?error=Account is deactivated");
|
|
2402
|
+
}
|
|
2403
|
+
const jwt2 = await AuthManager.generateToken(
|
|
2404
|
+
user.id,
|
|
2405
|
+
user.email,
|
|
2406
|
+
user.role,
|
|
2407
|
+
c.env.JWT_SECRET
|
|
2408
|
+
);
|
|
2409
|
+
AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax" });
|
|
2410
|
+
return c.redirect("/admin");
|
|
2411
|
+
}
|
|
2412
|
+
const existingUser = await oauthService.findUserByEmail(profile.email);
|
|
2413
|
+
if (existingUser) {
|
|
2414
|
+
if (!existingUser.is_active) {
|
|
2415
|
+
return c.redirect("/auth/login?error=Account is deactivated");
|
|
2416
|
+
}
|
|
2417
|
+
await oauthService.createOAuthAccount({
|
|
2418
|
+
userId: existingUser.id,
|
|
2419
|
+
provider: providerId,
|
|
2420
|
+
providerAccountId: profile.providerAccountId,
|
|
2421
|
+
accessToken: tokens.access_token,
|
|
2422
|
+
refreshToken: tokens.refresh_token,
|
|
2423
|
+
tokenExpiresAt: tokenExpiresAt ?? void 0,
|
|
2424
|
+
profileData: JSON.stringify(profile)
|
|
2425
|
+
});
|
|
2426
|
+
const jwt2 = await AuthManager.generateToken(
|
|
2427
|
+
existingUser.id,
|
|
2428
|
+
existingUser.email,
|
|
2429
|
+
existingUser.role,
|
|
2430
|
+
c.env.JWT_SECRET
|
|
2431
|
+
);
|
|
2432
|
+
AuthManager.setAuthCookie(c, jwt2, { sameSite: "Lax" });
|
|
2433
|
+
return c.redirect("/admin");
|
|
2434
|
+
}
|
|
2435
|
+
const newUserId = await oauthService.createUserFromOAuth(profile);
|
|
2436
|
+
await oauthService.createOAuthAccount({
|
|
2437
|
+
userId: newUserId,
|
|
2438
|
+
provider: providerId,
|
|
2439
|
+
providerAccountId: profile.providerAccountId,
|
|
2440
|
+
accessToken: tokens.access_token,
|
|
2441
|
+
refreshToken: tokens.refresh_token,
|
|
2442
|
+
tokenExpiresAt: tokenExpiresAt ?? void 0,
|
|
2443
|
+
profileData: JSON.stringify(profile)
|
|
2444
|
+
});
|
|
2445
|
+
const jwt = await AuthManager.generateToken(
|
|
2446
|
+
newUserId,
|
|
2447
|
+
profile.email.toLowerCase(),
|
|
2448
|
+
"viewer",
|
|
2449
|
+
c.env.JWT_SECRET
|
|
2450
|
+
);
|
|
2451
|
+
AuthManager.setAuthCookie(c, jwt, { sameSite: "Lax" });
|
|
2452
|
+
return c.redirect("/admin");
|
|
2453
|
+
} catch (error) {
|
|
2454
|
+
console.error("OAuth callback error:", error);
|
|
2455
|
+
const message = error instanceof Error ? error.message : "OAuth authentication failed";
|
|
2456
|
+
return c.redirect(`/auth/login?error=${encodeURIComponent(message)}`);
|
|
2457
|
+
}
|
|
2458
|
+
});
|
|
2459
|
+
oauthAPI.post("/link", async (c) => {
|
|
2460
|
+
try {
|
|
2461
|
+
const user = c.get("user");
|
|
2462
|
+
if (!user) {
|
|
2463
|
+
return c.json({ error: "Authentication required" }, 401);
|
|
2464
|
+
}
|
|
2465
|
+
const body = await c.req.json();
|
|
2466
|
+
const { provider } = body;
|
|
2467
|
+
if (!provider || !BUILT_IN_PROVIDERS[provider]) {
|
|
2468
|
+
return c.json({ error: "Invalid provider" }, 400);
|
|
2469
|
+
}
|
|
2470
|
+
const db = c.env.DB;
|
|
2471
|
+
const settings = await loadSettings(db);
|
|
2472
|
+
const creds = getProviderCredentials(settings, provider);
|
|
2473
|
+
if (!creds) {
|
|
2474
|
+
return c.json({ error: `OAuth provider "${provider}" is not configured` }, 400);
|
|
2475
|
+
}
|
|
2476
|
+
const oauthService = new OAuthService(db);
|
|
2477
|
+
const state = oauthService.generateState();
|
|
2478
|
+
const redirectUri = getCallbackUrl(c, provider);
|
|
2479
|
+
setCookie(c, STATE_COOKIE_NAME, state, {
|
|
2480
|
+
httpOnly: true,
|
|
2481
|
+
secure: true,
|
|
2482
|
+
sameSite: "Lax",
|
|
2483
|
+
maxAge: STATE_COOKIE_MAX_AGE,
|
|
2484
|
+
path: "/auth/oauth"
|
|
2485
|
+
});
|
|
2486
|
+
const authorizeUrl = oauthService.buildAuthorizeUrl(
|
|
2487
|
+
BUILT_IN_PROVIDERS[provider],
|
|
2488
|
+
creds.clientId,
|
|
2489
|
+
redirectUri,
|
|
2490
|
+
state
|
|
2491
|
+
);
|
|
2492
|
+
return c.json({ redirectUrl: authorizeUrl });
|
|
2493
|
+
} catch (error) {
|
|
2494
|
+
console.error("OAuth link error:", error);
|
|
2495
|
+
return c.json({ error: "Failed to initiate account linking" }, 500);
|
|
2496
|
+
}
|
|
2497
|
+
});
|
|
2498
|
+
oauthAPI.post("/unlink", async (c) => {
|
|
2499
|
+
try {
|
|
2500
|
+
const user = c.get("user");
|
|
2501
|
+
if (!user) {
|
|
2502
|
+
return c.json({ error: "Authentication required" }, 401);
|
|
2503
|
+
}
|
|
2504
|
+
const body = await c.req.json();
|
|
2505
|
+
const { provider } = body;
|
|
2506
|
+
if (!provider) {
|
|
2507
|
+
return c.json({ error: "Provider is required" }, 400);
|
|
2508
|
+
}
|
|
2509
|
+
const db = c.env.DB;
|
|
2510
|
+
const oauthService = new OAuthService(db);
|
|
2511
|
+
const success = await oauthService.unlinkOAuthAccount(user.userId, provider);
|
|
2512
|
+
if (!success) {
|
|
2513
|
+
return c.json({
|
|
2514
|
+
error: "Cannot unlink the only authentication method. Set a password first."
|
|
2515
|
+
}, 400);
|
|
2516
|
+
}
|
|
2517
|
+
return c.json({ success: true, message: `${provider} account unlinked` });
|
|
2518
|
+
} catch (error) {
|
|
2519
|
+
console.error("OAuth unlink error:", error);
|
|
2520
|
+
return c.json({ error: "Failed to unlink account" }, 500);
|
|
2521
|
+
}
|
|
2522
|
+
});
|
|
2523
|
+
oauthAPI.get("/accounts", async (c) => {
|
|
2524
|
+
try {
|
|
2525
|
+
const user = c.get("user");
|
|
2526
|
+
if (!user) {
|
|
2527
|
+
return c.json({ error: "Authentication required" }, 401);
|
|
2528
|
+
}
|
|
2529
|
+
const db = c.env.DB;
|
|
2530
|
+
const oauthService = new OAuthService(db);
|
|
2531
|
+
const accounts = await oauthService.findUserOAuthAccounts(user.userId);
|
|
2532
|
+
return c.json({
|
|
2533
|
+
accounts: accounts.map((a) => ({
|
|
2534
|
+
provider: a.provider,
|
|
2535
|
+
providerAccountId: a.provider_account_id,
|
|
2536
|
+
linkedAt: a.created_at
|
|
2537
|
+
}))
|
|
2538
|
+
});
|
|
2539
|
+
} catch (error) {
|
|
2540
|
+
console.error("OAuth accounts error:", error);
|
|
2541
|
+
return c.json({ error: "Failed to fetch linked accounts" }, 500);
|
|
2542
|
+
}
|
|
2543
|
+
});
|
|
2544
|
+
builder.addRoute("/auth/oauth", oauthAPI, {
|
|
2545
|
+
description: "OAuth2 social login endpoints",
|
|
2546
|
+
requiresAuth: false,
|
|
2547
|
+
priority: 100
|
|
2548
|
+
});
|
|
2549
|
+
builder.addMenuItem("OAuth Providers", "/admin/plugins/oauth-providers", {
|
|
2550
|
+
icon: "shield",
|
|
2551
|
+
order: 86,
|
|
2552
|
+
permissions: ["oauth:manage"]
|
|
2553
|
+
});
|
|
2554
|
+
builder.lifecycle({
|
|
2555
|
+
activate: async () => {
|
|
2556
|
+
console.info("\u2705 OAuth Providers plugin activated");
|
|
2557
|
+
},
|
|
2558
|
+
deactivate: async () => {
|
|
2559
|
+
console.info("\u274C OAuth Providers plugin deactivated");
|
|
2560
|
+
}
|
|
2561
|
+
});
|
|
2562
|
+
return builder.build();
|
|
2563
|
+
}
|
|
2564
|
+
var oauthProvidersPlugin = createOAuthProvidersPlugin();
|
|
2565
|
+
|
|
2004
2566
|
// src/plugins/core-plugins/ai-search-plugin/services/embedding.service.ts
|
|
2005
2567
|
var EmbeddingService = class {
|
|
2006
2568
|
constructor(ai) {
|
|
@@ -6024,6 +6586,11 @@ function createSonicJSApp(config = {}) {
|
|
|
6024
6586
|
}
|
|
6025
6587
|
}
|
|
6026
6588
|
app2.route("/admin/cache", cache_default.getRoutes());
|
|
6589
|
+
if (oauthProvidersPlugin.routes && oauthProvidersPlugin.routes.length > 0) {
|
|
6590
|
+
for (const route of oauthProvidersPlugin.routes) {
|
|
6591
|
+
app2.route(route.path, route.handler);
|
|
6592
|
+
}
|
|
6593
|
+
}
|
|
6027
6594
|
if (otpLoginPlugin.routes && otpLoginPlugin.routes.length > 0) {
|
|
6028
6595
|
for (const route of otpLoginPlugin.routes) {
|
|
6029
6596
|
app2.route(route.path, route.handler);
|
|
@@ -6119,6 +6686,6 @@ function createDb(d1) {
|
|
|
6119
6686
|
// src/index.ts
|
|
6120
6687
|
var VERSION = package_default.version;
|
|
6121
6688
|
|
|
6122
|
-
export { VERSION, createDb, createSonicJSApp, setupCoreMiddleware, setupCoreRoutes };
|
|
6689
|
+
export { BUILT_IN_PROVIDERS, OAuthService, VERSION, createDb, createOAuthProvidersPlugin, createSonicJSApp, oauthProvidersPlugin, setupCoreMiddleware, setupCoreRoutes };
|
|
6123
6690
|
//# sourceMappingURL=index.js.map
|
|
6124
6691
|
//# sourceMappingURL=index.js.map
|