@ahmedbaset/adminjs-hono 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.
Files changed (59) hide show
  1. package/.eslintrc.cjs +20 -0
  2. package/README.md +239 -0
  3. package/examples/auth.ts +76 -0
  4. package/examples/simple.ts +42 -0
  5. package/lib/authentication/login.handler.d.ts +11 -0
  6. package/lib/authentication/login.handler.d.ts.map +1 -0
  7. package/lib/authentication/login.handler.js +155 -0
  8. package/lib/authentication/logout.handler.d.ts +11 -0
  9. package/lib/authentication/logout.handler.d.ts.map +1 -0
  10. package/lib/authentication/logout.handler.js +50 -0
  11. package/lib/authentication/protected-routes.handler.d.ts +11 -0
  12. package/lib/authentication/protected-routes.handler.d.ts.map +1 -0
  13. package/lib/authentication/protected-routes.handler.js +26 -0
  14. package/lib/authentication/refresh.handler.d.ts +13 -0
  15. package/lib/authentication/refresh.handler.d.ts.map +1 -0
  16. package/lib/authentication/refresh.handler.js +42 -0
  17. package/lib/buildAuthenticatedRouter.d.ts +15 -0
  18. package/lib/buildAuthenticatedRouter.d.ts.map +1 -0
  19. package/lib/buildAuthenticatedRouter.js +61 -0
  20. package/lib/buildRouter.d.ts +53 -0
  21. package/lib/buildRouter.d.ts.map +1 -0
  22. package/lib/buildRouter.js +178 -0
  23. package/lib/convertRoutes.d.ts +9 -0
  24. package/lib/convertRoutes.d.ts.map +1 -0
  25. package/lib/convertRoutes.js +10 -0
  26. package/lib/errors.d.ts +10 -0
  27. package/lib/errors.d.ts.map +1 -0
  28. package/lib/errors.js +15 -0
  29. package/lib/formParser.d.ts +13 -0
  30. package/lib/formParser.d.ts.map +1 -0
  31. package/lib/formParser.js +53 -0
  32. package/lib/index.d.ts +55 -0
  33. package/lib/index.d.ts.map +1 -0
  34. package/lib/index.js +48 -0
  35. package/lib/logger.d.ts +7 -0
  36. package/lib/logger.d.ts.map +1 -0
  37. package/lib/logger.js +17 -0
  38. package/lib/session.d.ts +25 -0
  39. package/lib/session.d.ts.map +1 -0
  40. package/lib/session.js +56 -0
  41. package/lib/types.d.ts +46 -0
  42. package/lib/types.d.ts.map +1 -0
  43. package/lib/types.js +1 -0
  44. package/package.json +44 -0
  45. package/src/authentication/login.handler.ts +193 -0
  46. package/src/authentication/logout.handler.ts +62 -0
  47. package/src/authentication/protected-routes.handler.ts +38 -0
  48. package/src/authentication/refresh.handler.ts +59 -0
  49. package/src/buildAuthenticatedRouter.ts +92 -0
  50. package/src/buildRouter.ts +224 -0
  51. package/src/convertRoutes.ts +10 -0
  52. package/src/errors.ts +24 -0
  53. package/src/formParser.ts +73 -0
  54. package/src/index.ts +74 -0
  55. package/src/logger.ts +18 -0
  56. package/src/session.ts +71 -0
  57. package/src/types.ts +53 -0
  58. package/tsconfig.json +21 -0
  59. package/vitest.config.ts +12 -0
package/.eslintrc.cjs ADDED
@@ -0,0 +1,20 @@
1
+ module.exports = {
2
+ parser: '@typescript-eslint/parser',
3
+ extends: [
4
+ 'eslint:recommended',
5
+ 'plugin:@typescript-eslint/recommended',
6
+ ],
7
+ plugins: ['@typescript-eslint'],
8
+ env: {
9
+ node: true,
10
+ es2022: true,
11
+ },
12
+ parserOptions: {
13
+ ecmaVersion: 2022,
14
+ sourceType: 'module',
15
+ },
16
+ rules: {
17
+ '@typescript-eslint/no-explicit-any': 'warn',
18
+ '@typescript-eslint/no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
19
+ },
20
+ }
package/README.md ADDED
@@ -0,0 +1,239 @@
1
+ # @ahmedbaset/adminjs-hono
2
+
3
+ AdminJS adapter for [Hono](https://hono.dev/) web framework. This adapter allows you to integrate AdminJS admin panels into Hono applications with support for all JavaScript runtimes (Node.js, Deno, Bun, Cloudflare Workers, etc.).
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @ahmedbaset/adminjs-hono adminjs hono
9
+ ```
10
+
11
+ ## Features
12
+
13
+ - 🚀 Works with all Hono-supported runtimes (Node.js, Deno, Bun, Cloudflare Workers, etc.)
14
+ - 🔒 Built-in session-based authentication
15
+ - 📦 File upload support using Web Standards
16
+ - 🎨 Same API design as the Express adapter for easy migration
17
+ - 📝 Full TypeScript support
18
+ - ⚡ Lightweight and fast
19
+
20
+ ## Usage
21
+
22
+ ### Basic Usage (No Authentication)
23
+
24
+ ```typescript
25
+ import { Hono } from 'hono'
26
+ import AdminJS from 'adminjs'
27
+ import { buildRouter } from '@ahmedbaset/adminjs-hono'
28
+
29
+ const admin = new AdminJS({
30
+ databases: [],
31
+ rootPath: '/admin',
32
+ })
33
+
34
+ const app = new Hono()
35
+ const adminRouter = buildRouter(admin)
36
+
37
+ app.route('/admin', adminRouter)
38
+
39
+ export default app
40
+ ```
41
+
42
+ ### With Authentication
43
+
44
+ ```typescript
45
+ import { Hono } from 'hono'
46
+ import AdminJS from 'adminjs'
47
+ import { buildAuthenticatedRouter } from '@ahmedbaset/adminjs-hono'
48
+
49
+ const admin = new AdminJS({
50
+ databases: [],
51
+ rootPath: '/admin',
52
+ })
53
+
54
+ const app = new Hono()
55
+
56
+ const adminRouter = buildAuthenticatedRouter(
57
+ admin,
58
+ {
59
+ authenticate: async (email, password) => {
60
+ // Verify credentials against your database
61
+ if (email === 'admin@example.com' && password === 'password') {
62
+ return { email, name: 'Admin' }
63
+ }
64
+ return null
65
+ },
66
+ cookiePassword: 'some-secret-password-at-least-32-characters-long',
67
+ cookieName: 'adminjs',
68
+ },
69
+ undefined, // predefined app (optional)
70
+ {
71
+ // Session options
72
+ maxAge: 86400, // 24 hours
73
+ httpOnly: true,
74
+ secure: process.env.NODE_ENV === 'production',
75
+ }
76
+ )
77
+
78
+ app.route('/admin', adminRouter)
79
+
80
+ export default app
81
+ ```
82
+
83
+ ### Using an Existing Hono App
84
+
85
+ You can pass an existing Hono app instance to add custom middleware:
86
+
87
+ ```typescript
88
+ import { Hono } from 'hono'
89
+ import { logger } from 'hono/logger'
90
+ import AdminJS from 'adminjs'
91
+ import { buildRouter } from '@ahmedbaset/adminjs-hono'
92
+
93
+ const admin = new AdminJS({
94
+ databases: [],
95
+ rootPath: '/admin',
96
+ })
97
+
98
+ // Create a Hono app with custom middleware
99
+ const adminApp = new Hono()
100
+ adminApp.use('*', logger())
101
+
102
+ // Pass it to buildRouter
103
+ const adminRouter = buildRouter(admin, adminApp)
104
+
105
+ const app = new Hono()
106
+ app.route('/admin', adminRouter)
107
+
108
+ export default app
109
+ ```
110
+
111
+ ## API
112
+
113
+ ### `buildRouter(admin, predefinedApp?, uploadOptions?)`
114
+
115
+ Creates a Hono app with AdminJS routes (no authentication).
116
+
117
+ **Parameters:**
118
+ - `admin` (AdminJS): AdminJS instance
119
+ - `predefinedApp` (Hono, optional): Existing Hono app to use
120
+ - `uploadOptions` (UploadOptions, optional): File upload configuration
121
+
122
+ **Returns:** Hono app with AdminJS routes
123
+
124
+ ### `buildAuthenticatedRouter(admin, auth, predefinedApp?, sessionOptions?, uploadOptions?)`
125
+
126
+ Creates a Hono app with AdminJS routes protected by session authentication.
127
+
128
+ **Parameters:**
129
+ - `admin` (AdminJS): AdminJS instance
130
+ - `auth` (AuthenticationOptions): Authentication configuration
131
+ - `predefinedApp` (Hono, optional): Existing Hono app to use
132
+ - `sessionOptions` (SessionOptions, optional): Session cookie configuration
133
+ - `uploadOptions` (UploadOptions, optional): File upload configuration
134
+
135
+ **Returns:** Hono app with authenticated AdminJS routes
136
+
137
+ ## Configuration Options
138
+
139
+ ### AuthenticationOptions
140
+
141
+ ```typescript
142
+ {
143
+ cookiePassword: string // Required: Secret for session cookies
144
+ cookieName?: string // Optional: Cookie name (default: 'adminjs')
145
+ authenticate?: (email, password, context?) => Promise<CurrentAdmin | null>
146
+ maxRetries?: number | { count: number, duration: number }
147
+ provider?: BaseAuthProvider // Alternative to authenticate function
148
+ }
149
+ ```
150
+
151
+ ### SessionOptions
152
+
153
+ ```typescript
154
+ {
155
+ maxAge?: number // Session duration in seconds (default: 86400)
156
+ httpOnly?: boolean // HttpOnly flag (default: true)
157
+ secure?: boolean // Secure flag (default: false)
158
+ sameSite?: 'Strict' | 'Lax' | 'None' // SameSite policy (default: 'Lax')
159
+ domain?: string // Cookie domain
160
+ path?: string // Cookie path (default: '/')
161
+ }
162
+ ```
163
+
164
+ ### UploadOptions
165
+
166
+ ```typescript
167
+ {
168
+ uploadDir?: string // Upload directory path
169
+ maxFileSize?: number // Maximum file size in bytes
170
+ maxFieldsSize?: number // Maximum total fields size in bytes
171
+ maxFields?: number // Maximum number of fields
172
+ keepExtensions?: boolean // Keep file extensions
173
+ }
174
+ ```
175
+
176
+ ## Authentication Providers
177
+
178
+ You can use AdminJS authentication providers instead of the `authenticate` function:
179
+
180
+ ```typescript
181
+ import { buildAuthenticatedRouter } from '@ahmedbaset/adminjs-hono'
182
+ import { MyAuthProvider } from './my-auth-provider'
183
+
184
+ const adminRouter = buildAuthenticatedRouter(
185
+ admin,
186
+ {
187
+ provider: new MyAuthProvider(),
188
+ cookiePassword: 'secret',
189
+ }
190
+ )
191
+ ```
192
+
193
+ ## Differences from Express Adapter
194
+
195
+ The Hono adapter maintains API compatibility with the Express adapter, but there are some differences:
196
+
197
+ 1. **Runtime Support**: Works on all JavaScript runtimes, not just Node.js
198
+ 2. **File Uploads**: Uses Web Standards FormData API instead of express-formidable
199
+ 3. **Session Storage**: Uses in-memory storage by default (suitable for single-instance deployments)
200
+ 4. **Middleware**: Uses Hono middleware instead of Express middleware
201
+
202
+ ## Debugging
203
+
204
+ Set the `ADMINJS_HONO_DEBUG` environment variable to enable debug logging:
205
+
206
+ ```bash
207
+ ADMINJS_HONO_DEBUG=true node server.js
208
+ ```
209
+
210
+ ## Examples
211
+
212
+ See the [examples](./examples) directory for complete working examples:
213
+
214
+ - [simple.ts](./examples/simple.ts) - Basic usage without authentication
215
+ - [auth.ts](./examples/auth.ts) - Usage with authentication
216
+
217
+ ## Troubleshooting
218
+
219
+ ### Session not persisting
220
+
221
+ Make sure you're using the same `cookieName` across requests and that cookies are enabled in your browser. In production, set `secure: true` in session options when using HTTPS.
222
+
223
+ ### File uploads not working
224
+
225
+ Ensure the `uploadDir` exists and is writable. The adapter uses Web Standards FormData API, which may have different behavior across runtimes.
226
+
227
+ ### Assets not loading
228
+
229
+ Check that the AdminJS `rootPath` matches the path where you mount the router. For example, if `rootPath: '/admin'`, mount with `app.route('/admin', adminRouter)`.
230
+
231
+ ## License
232
+
233
+ MIT
234
+
235
+ ## Links
236
+
237
+ - [AdminJS Documentation](https://docs.adminjs.co/)
238
+ - [Hono Documentation](https://hono.dev/)
239
+ - [GitHub Repository](https://github.com/SoftwareBrothers/adminjs-hono)
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Example of AdminJS with Hono and authentication
3
+ *
4
+ * This example shows how to integrate AdminJS into a Hono application
5
+ * with session-based authentication.
6
+ */
7
+
8
+ import { Hono } from 'hono'
9
+ import { serve } from '@hono/node-server'
10
+ import AdminJS from 'adminjs'
11
+ import { buildAuthenticatedRouter } from '../src/index.js'
12
+
13
+ // Mock admin user for demonstration
14
+ const ADMIN = {
15
+ email: 'admin@example.com',
16
+ password: 'password',
17
+ name: 'Admin User',
18
+ }
19
+
20
+ // Create AdminJS instance
21
+ const admin = new AdminJS({
22
+ databases: [],
23
+ rootPath: '/admin',
24
+ resources: [],
25
+ })
26
+
27
+ // Build authenticated AdminJS router
28
+ const adminRouter = buildAuthenticatedRouter(
29
+ admin,
30
+ {
31
+ // Authentication function
32
+ authenticate: async (email, password) => {
33
+ // In production, verify against database with hashed passwords
34
+ if (email === ADMIN.email && password === ADMIN.password) {
35
+ return {
36
+ email: ADMIN.email,
37
+ name: ADMIN.name,
38
+ }
39
+ }
40
+ return null
41
+ },
42
+ // Session cookie configuration
43
+ cookiePassword: 'some-secret-password-at-least-32-characters-long',
44
+ cookieName: 'adminjs',
45
+ },
46
+ undefined, // No predefined app
47
+ {
48
+ // Session options
49
+ maxAge: 86400, // 24 hours
50
+ httpOnly: true,
51
+ secure: process.env.NODE_ENV === 'production',
52
+ sameSite: 'Lax',
53
+ }
54
+ )
55
+
56
+ // Create main Hono app
57
+ const app = new Hono()
58
+
59
+ // Mount AdminJS router
60
+ app.route('/admin', adminRouter)
61
+
62
+ // Add a simple home route
63
+ app.get('/', (c) => {
64
+ return c.text('AdminJS is running at /admin (login required)')
65
+ })
66
+
67
+ // Start server
68
+ const port = 3000
69
+ console.log(`Server is running on http://localhost:${port}`)
70
+ console.log(`AdminJS is available at http://localhost:${port}/admin`)
71
+ console.log(`Login with: ${ADMIN.email} / ${ADMIN.password}`)
72
+
73
+ serve({
74
+ fetch: app.fetch,
75
+ port,
76
+ })
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Simple example of AdminJS with Hono (no authentication)
3
+ *
4
+ * This example shows how to integrate AdminJS into a Hono application
5
+ * without authentication. Suitable for development environments.
6
+ */
7
+
8
+ import { Hono } from 'hono'
9
+ import { serve } from '@hono/node-server'
10
+ import AdminJS from 'adminjs'
11
+ import { buildRouter } from '../src/index.js'
12
+
13
+ // Create AdminJS instance
14
+ const admin = new AdminJS({
15
+ databases: [],
16
+ rootPath: '/admin',
17
+ resources: [],
18
+ })
19
+
20
+ // Build AdminJS router
21
+ const adminRouter = buildRouter(admin)
22
+
23
+ // Create main Hono app
24
+ const app = new Hono()
25
+
26
+ // Mount AdminJS router
27
+ app.route('/admin', adminRouter)
28
+
29
+ // Add a simple home route
30
+ app.get('/', (c) => {
31
+ return c.text('AdminJS is running at /admin')
32
+ })
33
+
34
+ // Start server
35
+ const port = 3000
36
+ console.log(`Server is running on http://localhost:${port}`)
37
+ console.log(`AdminJS is available at http://localhost:${port}/admin`)
38
+
39
+ serve({
40
+ fetch: app.fetch,
41
+ port,
42
+ })
@@ -0,0 +1,11 @@
1
+ import type AdminJS from 'adminjs';
2
+ import type { Hono } from 'hono';
3
+ import type { AuthenticationOptions } from '../types.js';
4
+ /**
5
+ * Registers login routes with the Hono app
6
+ * @param app - Hono app instance
7
+ * @param admin - AdminJS instance
8
+ * @param auth - Authentication options
9
+ */
10
+ export declare function withLogin(app: Hono, admin: AdminJS, auth: AuthenticationOptions): void;
11
+ //# sourceMappingURL=login.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.handler.d.ts","sourceRoot":"","sources":["../../src/authentication/login.handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,EAAE,IAAI,EAAW,MAAM,MAAM,CAAA;AACzC,OAAO,KAAK,EAGV,qBAAqB,EAEtB,MAAM,aAAa,CAAA;AA8EpB;;;;;GAKG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,qBAAqB,GAC1B,IAAI,CAiGN"}
@@ -0,0 +1,155 @@
1
+ import { INVALID_AUTH_CONFIG_ERROR, WrongArgumentError } from '../errors.js';
2
+ /**
3
+ * Normalizes the login path by removing the root path
4
+ * @param admin - AdminJS instance
5
+ * @returns Normalized login path
6
+ */
7
+ function getLoginPath(admin) {
8
+ const { loginPath, rootPath } = admin.options;
9
+ const normalizedLoginPath = loginPath.replace(rootPath, '');
10
+ return normalizedLoginPath.startsWith('/')
11
+ ? normalizedLoginPath
12
+ : `/${normalizedLoginPath}`;
13
+ }
14
+ /**
15
+ * Manages login retry attempts per IP address
16
+ */
17
+ class Retry {
18
+ static retriesContainer = new Map();
19
+ lastRetry;
20
+ retriesCount = 0;
21
+ constructor(ip) {
22
+ const existing = Retry.retriesContainer.get(ip);
23
+ if (existing) {
24
+ return existing;
25
+ }
26
+ Retry.retriesContainer.set(ip, this);
27
+ }
28
+ /**
29
+ * Checks if a login attempt is allowed based on retry limits
30
+ * @param maxRetries - Maximum retry configuration
31
+ * @returns true if login is allowed, false otherwise
32
+ */
33
+ canLogin(maxRetries) {
34
+ if (maxRetries === undefined) {
35
+ return true;
36
+ }
37
+ // Convert number to AuthenticationMaxRetriesOptions
38
+ let retryConfig;
39
+ if (typeof maxRetries === 'number') {
40
+ retryConfig = {
41
+ count: maxRetries,
42
+ duration: 60, // per minute
43
+ };
44
+ }
45
+ else {
46
+ retryConfig = maxRetries;
47
+ }
48
+ if (retryConfig.count <= 0) {
49
+ return true;
50
+ }
51
+ // Check if duration has passed since last retry
52
+ if (!this.lastRetry ||
53
+ new Date().getTime() - this.lastRetry.getTime() >
54
+ retryConfig.duration * 1000) {
55
+ // Reset counter
56
+ this.lastRetry = new Date();
57
+ this.retriesCount = 1;
58
+ return true;
59
+ }
60
+ else {
61
+ // Increment counter
62
+ this.lastRetry = new Date();
63
+ this.retriesCount++;
64
+ return this.retriesCount <= retryConfig.count;
65
+ }
66
+ }
67
+ }
68
+ /**
69
+ * Registers login routes with the Hono app
70
+ * @param app - Hono app instance
71
+ * @param admin - AdminJS instance
72
+ * @param auth - Authentication options
73
+ */
74
+ export function withLogin(app, admin, auth) {
75
+ const { rootPath } = admin.options;
76
+ const loginPath = getLoginPath(admin);
77
+ const { provider } = auth;
78
+ const providerProps = provider?.getUiProps?.() ?? {};
79
+ // GET /login - Render login page
80
+ app.get(loginPath, async (c) => {
81
+ const baseProps = {
82
+ action: admin.options.loginPath,
83
+ errorMessage: null,
84
+ };
85
+ const login = await admin.renderLogin({
86
+ ...baseProps,
87
+ ...providerProps,
88
+ });
89
+ return c.html(login);
90
+ });
91
+ // POST /login - Handle login submission
92
+ app.post(loginPath, async (c) => {
93
+ // Get client IP for retry tracking
94
+ const ip = c.req.header('x-forwarded-for') || c.req.header('x-real-ip') || 'unknown';
95
+ // Check retry limits
96
+ if (!new Retry(ip).canLogin(auth.maxRetries)) {
97
+ const login = await admin.renderLogin({
98
+ action: admin.options.loginPath,
99
+ errorMessage: 'tooManyRequests',
100
+ ...providerProps,
101
+ });
102
+ return c.html(login);
103
+ }
104
+ const context = { req: c, res: c };
105
+ let adminUser;
106
+ try {
107
+ if (provider) {
108
+ // Use authentication provider
109
+ const fields = c.get('fields') || {};
110
+ adminUser = await provider.handleLogin({
111
+ headers: Object.fromEntries(c.req.raw.headers.entries()),
112
+ query: c.req.query(),
113
+ params: c.req.param(),
114
+ data: fields,
115
+ }, context);
116
+ }
117
+ else if (auth.authenticate) {
118
+ // Use authenticate function
119
+ const fields = c.get('fields') || {};
120
+ const { email, password } = fields;
121
+ adminUser = await auth.authenticate(email, password, context);
122
+ }
123
+ else {
124
+ throw new WrongArgumentError(INVALID_AUTH_CONFIG_ERROR);
125
+ }
126
+ }
127
+ catch (error) {
128
+ const errorMessage = error.message || error.error || 'invalidCredentials';
129
+ const loginPage = await admin.renderLogin({
130
+ action: admin.options.loginPath,
131
+ errorMessage,
132
+ ...providerProps,
133
+ });
134
+ return c.html(loginPage, 400);
135
+ }
136
+ if (adminUser) {
137
+ // Store user in session
138
+ const session = c.get('session');
139
+ session.adminUser = adminUser;
140
+ // Redirect to original path or root
141
+ const redirectTo = session.redirectTo || rootPath;
142
+ delete session.redirectTo;
143
+ return c.redirect(redirectTo, 302);
144
+ }
145
+ else {
146
+ // Invalid credentials
147
+ const login = await admin.renderLogin({
148
+ action: admin.options.loginPath,
149
+ errorMessage: 'invalidCredentials',
150
+ ...providerProps,
151
+ });
152
+ return c.html(login);
153
+ }
154
+ });
155
+ }
@@ -0,0 +1,11 @@
1
+ import type AdminJS from 'adminjs';
2
+ import type { Hono } from 'hono';
3
+ import type { AuthenticationOptions } from '../types.js';
4
+ /**
5
+ * Registers logout route with the Hono app
6
+ * @param app - Hono app instance
7
+ * @param admin - AdminJS instance
8
+ * @param auth - Authentication options
9
+ */
10
+ export declare function withLogout(app: Hono, admin: AdminJS, auth: AuthenticationOptions): void;
11
+ //# sourceMappingURL=logout.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logout.handler.d.ts","sourceRoot":"","sources":["../../src/authentication/logout.handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,EAAE,IAAI,EAAW,MAAM,MAAM,CAAA;AAEzC,OAAO,KAAK,EAAE,qBAAqB,EAAiB,MAAM,aAAa,CAAA;AAgBvE;;;;;GAKG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,qBAAqB,GAC1B,IAAI,CAgCN"}
@@ -0,0 +1,50 @@
1
+ import { getCookie } from 'hono/cookie';
2
+ import { destroySession } from '../session.js';
3
+ /**
4
+ * Normalizes the logout path by removing the root path
5
+ * @param admin - AdminJS instance
6
+ * @returns Normalized logout path
7
+ */
8
+ function getLogoutPath(admin) {
9
+ const { logoutPath, rootPath } = admin.options;
10
+ const normalizedLogoutPath = logoutPath.replace(rootPath, '');
11
+ return normalizedLogoutPath.startsWith('/')
12
+ ? normalizedLogoutPath
13
+ : `/${normalizedLogoutPath}`;
14
+ }
15
+ /**
16
+ * Registers logout route with the Hono app
17
+ * @param app - Hono app instance
18
+ * @param admin - AdminJS instance
19
+ * @param auth - Authentication options
20
+ */
21
+ export function withLogout(app, admin, auth) {
22
+ const logoutPath = getLogoutPath(admin);
23
+ const { provider } = auth;
24
+ app.get(logoutPath, async (c) => {
25
+ // Call provider's handleLogout if available
26
+ if (provider) {
27
+ try {
28
+ await provider.handleLogout({ req: c, res: c });
29
+ }
30
+ catch (error) {
31
+ // Fail silently and continue with logout
32
+ console.error('Provider logout error:', error);
33
+ }
34
+ }
35
+ // Get session ID and destroy session
36
+ const cookieName = auth.cookieName || 'adminjs';
37
+ const sessionId = getCookie(c, cookieName);
38
+ if (sessionId) {
39
+ destroySession(sessionId);
40
+ }
41
+ // Clear session from context
42
+ const session = c.get('session');
43
+ if (session) {
44
+ delete session.adminUser;
45
+ delete session.redirectTo;
46
+ }
47
+ // Redirect to login page
48
+ return c.redirect(admin.options.loginPath);
49
+ });
50
+ }
@@ -0,0 +1,11 @@
1
+ import type AdminJS from 'adminjs';
2
+ import type { Hono } from 'hono';
3
+ /**
4
+ * Registers middleware to protect routes that require authentication
5
+ * Redirects unauthenticated requests to the login page
6
+ *
7
+ * @param app - Hono app instance
8
+ * @param admin - AdminJS instance
9
+ */
10
+ export declare function withProtectedRoutesHandler(app: Hono, admin: AdminJS): void;
11
+ //# sourceMappingURL=protected-routes.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protected-routes.handler.d.ts","sourceRoot":"","sources":["../../src/authentication/protected-routes.handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,EAAE,IAAI,EAA8B,MAAM,MAAM,CAAA;AAG5D;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,OAAO,GACb,IAAI,CAuBN"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Registers middleware to protect routes that require authentication
3
+ * Redirects unauthenticated requests to the login page
4
+ *
5
+ * @param app - Hono app instance
6
+ * @param admin - AdminJS instance
7
+ */
8
+ export function withProtectedRoutesHandler(app, admin) {
9
+ const { loginPath } = admin.options;
10
+ const authorizedRoutesMiddleware = async (c, next) => {
11
+ const session = c.get('session');
12
+ // Check if user is authenticated
13
+ if (!session || !session.adminUser) {
14
+ // Store the original path for redirect after login
15
+ session.redirectTo = c.req.path;
16
+ // Redirect to login page
17
+ return c.redirect(loginPath);
18
+ }
19
+ // User is authenticated, proceed
20
+ return next();
21
+ };
22
+ // Apply middleware to all routes
23
+ // Note: This should be registered after login/logout routes
24
+ // so they remain accessible without authentication
25
+ app.use('*', authorizedRoutesMiddleware);
26
+ }
@@ -0,0 +1,13 @@
1
+ import type AdminJS from 'adminjs';
2
+ import type { Hono } from 'hono';
3
+ import type { AuthenticationOptions } from '../types.js';
4
+ /**
5
+ * Registers token refresh route with the Hono app
6
+ * Delegates to authentication provider's refresh method if available
7
+ *
8
+ * @param app - Hono app instance
9
+ * @param admin - AdminJS instance
10
+ * @param auth - Authentication options
11
+ */
12
+ export declare function withRefresh(app: Hono, admin: AdminJS, auth: AuthenticationOptions): void;
13
+ //# sourceMappingURL=refresh.handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refresh.handler.d.ts","sourceRoot":"","sources":["../../src/authentication/refresh.handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,EAAE,IAAI,EAAW,MAAM,MAAM,CAAA;AACzC,OAAO,KAAK,EAAE,qBAAqB,EAAiB,MAAM,aAAa,CAAA;AAEvE;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,IAAI,EACT,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,qBAAqB,GAC1B,IAAI,CA0CN"}