@owox/idp-better-auth 0.5.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/README.md +183 -0
  2. package/dist/adapters/database.d.ts +29 -0
  3. package/dist/adapters/database.d.ts.map +1 -0
  4. package/dist/adapters/database.js +85 -0
  5. package/dist/auth/auth-config.d.ts +4 -0
  6. package/dist/auth/auth-config.d.ts.map +1 -0
  7. package/dist/auth/auth-config.js +72 -0
  8. package/dist/index.d.ts +15 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +16 -0
  11. package/dist/providers/better-auth-provider.d.ts +34 -0
  12. package/dist/providers/better-auth-provider.d.ts.map +1 -0
  13. package/dist/providers/better-auth-provider.js +99 -0
  14. package/dist/services/authentication-service.d.ts +23 -0
  15. package/dist/services/authentication-service.d.ts.map +1 -0
  16. package/dist/services/authentication-service.js +199 -0
  17. package/dist/services/crypto-service.d.ts +18 -0
  18. package/dist/services/crypto-service.d.ts.map +1 -0
  19. package/dist/services/crypto-service.js +100 -0
  20. package/dist/services/database-service.d.ts +14 -0
  21. package/dist/services/database-service.d.ts.map +1 -0
  22. package/dist/services/database-service.js +142 -0
  23. package/dist/services/magic-link-service.d.ts +10 -0
  24. package/dist/services/magic-link-service.d.ts.map +1 -0
  25. package/dist/services/magic-link-service.js +42 -0
  26. package/dist/services/middleware-service.d.ts +15 -0
  27. package/dist/services/middleware-service.d.ts.map +1 -0
  28. package/dist/services/middleware-service.js +38 -0
  29. package/dist/services/page-service.d.ts +23 -0
  30. package/dist/services/page-service.d.ts.map +1 -0
  31. package/dist/services/page-service.js +331 -0
  32. package/dist/services/request-handler-service.d.ts +10 -0
  33. package/dist/services/request-handler-service.d.ts.map +1 -0
  34. package/dist/services/request-handler-service.js +50 -0
  35. package/dist/services/template-service.d.ts +28 -0
  36. package/dist/services/template-service.d.ts.map +1 -0
  37. package/dist/services/template-service.js +198 -0
  38. package/dist/services/token-service.d.ts +15 -0
  39. package/dist/services/token-service.d.ts.map +1 -0
  40. package/dist/services/token-service.js +108 -0
  41. package/dist/services/user-management-service.d.ts +74 -0
  42. package/dist/services/user-management-service.d.ts.map +1 -0
  43. package/dist/services/user-management-service.js +396 -0
  44. package/dist/templates/admin-add-user.html +298 -0
  45. package/dist/templates/admin-dashboard.html +214 -0
  46. package/dist/templates/admin-user-details.html +278 -0
  47. package/dist/templates/password-setup.html +267 -0
  48. package/dist/templates/password-success.html +197 -0
  49. package/dist/templates/sign-in.html +201 -0
  50. package/dist/types/auth-session.d.ts +25 -0
  51. package/dist/types/auth-session.d.ts.map +1 -0
  52. package/dist/types/auth-session.js +1 -0
  53. package/dist/types/database-models.d.ts +54 -0
  54. package/dist/types/database-models.d.ts.map +1 -0
  55. package/dist/types/database-models.js +1 -0
  56. package/dist/types/index.d.ts +45 -0
  57. package/dist/types/index.d.ts.map +1 -0
  58. package/dist/types/index.js +2 -0
  59. package/package.json +69 -0
package/README.md ADDED
@@ -0,0 +1,183 @@
1
+ # @owox/idp-better-auth
2
+
3
+ Better Auth IDP provider for OWOX Data Marts authentication.
4
+
5
+ ## Setup
6
+
7
+ ### 1. Environment Configuration
8
+
9
+ Create or update your `.env` file with the required settings:
10
+
11
+ ```env
12
+ # Required
13
+ IDP_PROVIDER=better-auth
14
+ IDP_BETTER_AUTH_SECRET=your-super-secret-key-at-least-32-characters-long
15
+
16
+ # Database (SQLite - recommended for getting started)
17
+ IDP_BETTER_AUTH_DATABASE_TYPE=sqlite
18
+ IDP_BETTER_AUTH_SQLITE_DB_PATH=./data/auth.db
19
+
20
+ # Optional
21
+ IDP_BETTER_AUTH_BASE_URL=http://localhost:3000
22
+ IDP_BETTER_AUTH_MAGIC_LINK_TTL=3600
23
+ IDP_BETTER_AUTH_SESSION_MAX_AGE=86400
24
+ IDP_BETTER_AUTH_TRUSTED_ORIGINS=http://localhost:3000,http://localhost:3001
25
+ ```
26
+
27
+ #### Tip
28
+
29
+ To generate a random secret key, you can use the following command:
30
+
31
+ ```bash
32
+ openssl rand -base64 32
33
+ ```
34
+
35
+ ### 2. MySQL Configuration (Alternative)
36
+
37
+ If you prefer MySQL instead of SQLite:
38
+
39
+ ```env
40
+ IDP_PROVIDER=better-auth
41
+ IDP_BETTER_AUTH_SECRET=your-super-secret-key-at-least-32-characters-long
42
+
43
+ IDP_BETTER_AUTH_DATABASE_TYPE=mysql
44
+ IDP_BETTER_AUTH_MYSQL_HOST=localhost
45
+ IDP_BETTER_AUTH_MYSQL_USER=root
46
+ IDP_BETTER_AUTH_MYSQL_PASSWORD=your-password
47
+ IDP_BETTER_AUTH_MYSQL_DATABASE=owox_auth
48
+ IDP_BETTER_AUTH_MYSQL_PORT=3306
49
+ ```
50
+
51
+ ### 3. Start the Application
52
+
53
+ ```bash
54
+ owox serve
55
+ ```
56
+
57
+ or if .env file doesn't exported:
58
+
59
+ **Linux/macOS:**
60
+
61
+ ```bash
62
+ export $(grep -v '^#' .env | grep -v '^$' | xargs) && owox serve
63
+ ```
64
+
65
+ **Windows (PowerShell):**
66
+
67
+ ```powershell
68
+ Get-Content .env | Where-Object {$_ -notmatch '^#' -and $_ -notmatch '^$'} | ForEach-Object {$name, $value = $_.split('=', 2); Set-Variable -Name $name -Value $value}; owox serve
69
+ ```
70
+
71
+ **Windows (Command Prompt):**
72
+
73
+ ```cmd
74
+ for /f "usebackq tokens=1,2 delims==" %i in (.env) do set %i=%j
75
+ owox serve
76
+ ```
77
+
78
+ The authentication system will be available at:
79
+
80
+ - Sign in page: `http://localhost:3000/auth/sign-in`
81
+ - Admin dashboard: `http://localhost:3000/auth/dashboard`
82
+
83
+ ### 4. Add Your First Admin User
84
+
85
+ ```bash
86
+ # Add an admin user and get a magic link
87
+ export $(grep -v '^#' .env | grep -v '^$' | xargs) && owox idp add-user admin@yourdomain.com
88
+ ```
89
+
90
+ Copy the magic link from the output and open it in your browser to set up your admin account.
91
+
92
+ ## Authentication Flow
93
+
94
+ ### For End Users
95
+
96
+ 1. **Sign In**: Navigate to `/auth/sign-in`
97
+ 2. **Enter credentials**: Email and password
98
+ 3. **Dashboard access**: After login, access admin features at `/auth/dashboard`
99
+
100
+ ### For New Users (Admin Invitation)
101
+
102
+ 1. **Admin invites**: Admin uses the dashboard to invite new users via magic link
103
+ 2. **Magic link**: New user receives a magic link from user who invited them
104
+ 3. **Password setup**: User goes to magic link and sets their password
105
+ 4. **Access granted**: User can now sign in normally
106
+
107
+ ## Admin Panel Features
108
+
109
+ The admin dashboard (`/auth/dashboard`) provides:
110
+
111
+ - **User management**: View all users, their roles, and activity
112
+ - **Add users**: Invite new users with specific roles (admin/editor/viewer)
113
+ - **Role management**: Assign different permission levels
114
+ - **Magic links**: Generate new magic links for existing users
115
+
116
+ ### User Roles
117
+
118
+ - **Admin**: Full access, can manage all users and invite any role
119
+ - **Editor**: Can invite editors and viewers
120
+ - **Viewer**: Can only invite other viewers
121
+
122
+ ## Database Management
123
+
124
+ The database schema is automatically created on first startup. For SQLite, the file will be created at the path specified in `IDP_BETTER_AUTH_SQLITE_DB_PATH` or default path in system application temp directory.
125
+
126
+ ### SQLite (Default)
127
+
128
+ - File-based database
129
+ - No additional setup required
130
+ - Good for development and small deployments
131
+
132
+ ### MySQL
133
+
134
+ - Requires MySQL server
135
+ - Create database manually: `CREATE DATABASE owox_auth;`
136
+ - Create user if needed: `CREATE USER 'owox_auth_user'@'localhost' IDENTIFIED BY 'your_password';`
137
+ - Grant privileges: `GRANT ALL PRIVILEGES ON owox_auth.* TO 'owox_auth_user'@'localhost';`
138
+ - Flush privileges: `FLUSH PRIVILEGES;`
139
+ - Tables are created automatically
140
+
141
+ ## Command Line Tools
142
+
143
+ ### Add User
144
+
145
+ ```bash
146
+ owox idp add-user user@example.com
147
+ ```
148
+
149
+ ## Configuration Reference
150
+
151
+ | Variable | Required | Default | Description |
152
+ | --------------------------------- | :------: | :-----------------------: | ------------------------------------------- |
153
+ | `IDP_PROVIDER` | **Yes** | – | Set to `better-auth` |
154
+ | `IDP_BETTER_AUTH_SECRET` | **Yes** | – | Secret key for signing (min. 32 characters) |
155
+ | `IDP_BETTER_AUTH_DATABASE_TYPE` | No | `sqlite` | Database type: `sqlite` or `mysql` |
156
+ | `IDP_BETTER_AUTH_SQLITE_DB_PATH` | No | `<system temp directory>` | SQLite database file path |
157
+ | `IDP_BETTER_AUTH_BASE_URL` | No | `http://localhost:3000` | Base URL for magic links |
158
+ | `IDP_BETTER_AUTH_MAGIC_LINK_TTL` | No | `3600` (1 hour) | Magic link expiration (seconds) |
159
+ | `IDP_BETTER_AUTH_SESSION_MAX_AGE` | No | `604800` (7 days) | Session duration (seconds) |
160
+ | `IDP_BETTER_AUTH_MYSQL_HOST` | No | `localhost` | MySQL host |
161
+ | `IDP_BETTER_AUTH_MYSQL_USER` | No | `root` | MySQL user |
162
+ | `IDP_BETTER_AUTH_MYSQL_PASSWORD` | No | `your-password` | MySQL password |
163
+ | `IDP_BETTER_AUTH_MYSQL_DATABASE` | No | `owox_auth` | MySQL database |
164
+ | `IDP_BETTER_AUTH_MYSQL_PORT` | No | `3306` | MySQL port |
165
+ | `IDP_BETTER_AUTH_TRUSTED_ORIGINS` | No | `http://localhost:3000` | Trusted origins for auth service |
166
+
167
+ ## Troubleshooting
168
+
169
+ ### "IDP_BETTER_AUTH_SECRET is not set" Error
170
+
171
+ Make sure your `.env` file contains a valid `IDP_BETTER_AUTH_SECRET` with at least 32 characters.
172
+
173
+ ### Database Connection Issues
174
+
175
+ For MySQL, verify your connection settings and ensure the database exists.
176
+
177
+ ### Magic Links Not Working
178
+
179
+ Check that `IDP_BETTER_AUTH_BASE_URL` matches your application URL and that the magic link hasn't expired.
180
+
181
+ ### Permission Denied
182
+
183
+ Ensure the user has the correct role permissions for the action they're trying to perform.
@@ -0,0 +1,29 @@
1
+ import type { DatabaseConfig, SqliteConfig, MySqlConfig } from '../types/index.js';
2
+ /**
3
+ * Determines the SQLite database file path for IDP based on configuration.
4
+ *
5
+ * If `IDP_BETTER_AUTH_SQLITE_DB_PATH` environment variable is set, uses that path directly.
6
+ * Otherwise, uses cross-platform application data directory with 'owox/idp/auth.db' structure.
7
+ * Automatically creates the database directory if it doesn't exist.
8
+ *
9
+ * @returns The absolute path to the SQLite database file for IDP
10
+ * @throws {Error} When database directory cannot be created due to permissions or other filesystem errors
11
+ */
12
+ declare function getIdpSqliteDatabasePath(): string;
13
+ /**
14
+ * Create SQLite database adapter for Better Auth
15
+ */
16
+ export declare function createSqliteAdapter(config: SqliteConfig): Promise<unknown>;
17
+ /**
18
+ * Create MySQL database adapter for Better Auth
19
+ */
20
+ export declare function createMysqlAdapter(config: MySqlConfig): Promise<unknown>;
21
+ /**
22
+ * Create database adapter based on configuration
23
+ */
24
+ export declare function createDatabaseAdapter(config: DatabaseConfig): Promise<unknown>;
25
+ /**
26
+ * Export the IDP SQLite database path function for external use
27
+ */
28
+ export { getIdpSqliteDatabasePath };
29
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/adapters/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAKnF;;;;;;;;;GASG;AACH,iBAAS,wBAAwB,IAAI,MAAM,CA6B1C;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAQhF;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAiB9E;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CASpF;AAED;;GAEG;AACH,OAAO,EAAE,wBAAwB,EAAE,CAAC"}
@@ -0,0 +1,85 @@
1
+ import envPaths from 'env-paths';
2
+ import { existsSync, mkdirSync } from 'fs';
3
+ import { dirname, join } from 'path';
4
+ /**
5
+ * Determines the SQLite database file path for IDP based on configuration.
6
+ *
7
+ * If `IDP_BETTER_AUTH_SQLITE_DB_PATH` environment variable is set, uses that path directly.
8
+ * Otherwise, uses cross-platform application data directory with 'owox/idp/auth.db' structure.
9
+ * Automatically creates the database directory if it doesn't exist.
10
+ *
11
+ * @returns The absolute path to the SQLite database file for IDP
12
+ * @throws {Error} When database directory cannot be created due to permissions or other filesystem errors
13
+ */
14
+ function getIdpSqliteDatabasePath() {
15
+ const envDbPath = process.env.IDP_BETTER_AUTH_SQLITE_DB_PATH;
16
+ let dbPath;
17
+ if (envDbPath) {
18
+ console.log(`Using IDP SQLite database path from \`IDP_BETTER_AUTH_SQLITE_DB_PATH\` env: ${envDbPath}`);
19
+ dbPath = envDbPath;
20
+ }
21
+ else {
22
+ const paths = envPaths('owox', { suffix: '' });
23
+ dbPath = join(paths.data, 'idp', 'auth.db');
24
+ console.log(`Using system app data directory for IDP SQLite: ${dbPath}`);
25
+ }
26
+ const dbDir = dirname(dbPath);
27
+ if (!existsSync(dbDir)) {
28
+ try {
29
+ mkdirSync(dbDir, { recursive: true });
30
+ console.log(`Created IDP SQLite database directory: ${dbDir}`);
31
+ }
32
+ catch (error) {
33
+ throw new Error(`Failed to create IDP SQLite database directory: ${dbDir}. ${error instanceof Error ? error.message : String(error)}`);
34
+ }
35
+ }
36
+ return dbPath;
37
+ }
38
+ /**
39
+ * Create SQLite database adapter for Better Auth
40
+ */
41
+ export async function createSqliteAdapter(config) {
42
+ // Dynamic import to handle optional dependency
43
+ const { default: Database } = await import('better-sqlite3');
44
+ // Use configured path or default to smart path resolution
45
+ const dbPath = config.filename || getIdpSqliteDatabasePath();
46
+ return new Database(dbPath);
47
+ }
48
+ /**
49
+ * Create MySQL database adapter for Better Auth
50
+ */
51
+ export async function createMysqlAdapter(config) {
52
+ try {
53
+ const mysql = await import('mysql2/promise');
54
+ return mysql.default.createPool({
55
+ host: config.host,
56
+ user: config.user,
57
+ password: config.password,
58
+ database: config.database,
59
+ port: config.port || 3306,
60
+ waitForConnections: true,
61
+ connectionLimit: 10,
62
+ queueLimit: 0,
63
+ });
64
+ }
65
+ catch {
66
+ throw new Error('mysql2 is required for MySQL support. Install it with: npm install mysql2');
67
+ }
68
+ }
69
+ /**
70
+ * Create database adapter based on configuration
71
+ */
72
+ export async function createDatabaseAdapter(config) {
73
+ switch (config.type) {
74
+ case 'sqlite':
75
+ return await createSqliteAdapter(config);
76
+ case 'mysql':
77
+ return await createMysqlAdapter(config);
78
+ default:
79
+ throw new Error(`Unsupported database type: ${config.type}`);
80
+ }
81
+ }
82
+ /**
83
+ * Export the IDP SQLite database path function for external use
84
+ */
85
+ export { getIdpSqliteDatabasePath };
@@ -0,0 +1,4 @@
1
+ import { betterAuth } from 'better-auth';
2
+ import { BetterAuthConfig } from '../types/index.js';
3
+ export declare function createBetterAuthConfig(config: BetterAuthConfig): Promise<ReturnType<typeof betterAuth>>;
4
+ //# sourceMappingURL=auth-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth-config.d.ts","sourceRoot":"","sources":["../../src/auth/auth-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAIrD,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC,CAmGxC"}
@@ -0,0 +1,72 @@
1
+ import { betterAuth } from 'better-auth';
2
+ import { magicLink, organization } from 'better-auth/plugins';
3
+ import { createDatabaseAdapter } from '../adapters/database.js';
4
+ import { createAccessControl } from 'better-auth/plugins/access';
5
+ export async function createBetterAuthConfig(config) {
6
+ const database = await createDatabaseAdapter(config.database);
7
+ const plugins = [];
8
+ plugins.push(magicLink({
9
+ sendMagicLink: async ({ email, token, url }) => {
10
+ global.lastMagicLink = url;
11
+ global.lastEmail = email;
12
+ global.lastToken = token;
13
+ },
14
+ expiresIn: 3600, // 1 hour
15
+ disableSignUp: false,
16
+ }));
17
+ const ac = createAccessControl({
18
+ project: ['create', 'update', 'delete', 'view'],
19
+ });
20
+ const adminRole = ac.newRole({
21
+ project: ['create', 'update', 'delete', 'view'],
22
+ });
23
+ const editorRole = ac.newRole({
24
+ project: ['create', 'update', 'delete', 'view'],
25
+ });
26
+ const viewerRole = ac.newRole({
27
+ project: ['view'],
28
+ });
29
+ plugins.push(organization({
30
+ ac,
31
+ roles: {
32
+ admin: adminRole,
33
+ editor: editorRole,
34
+ viewer: viewerRole,
35
+ },
36
+ allowUserToCreateOrganization: false,
37
+ organizationLimit: 1,
38
+ async sendInvitationEmail(_data) {
39
+ return;
40
+ },
41
+ }));
42
+ const authConfig = {
43
+ database,
44
+ plugins,
45
+ session: {
46
+ expiresIn: config.session?.maxAge || 60 * 60 * 24 * 7,
47
+ updateAge: 60 * 60 * 24,
48
+ },
49
+ trustedOrigins: config.baseURL ? [config.baseURL] : ['http://localhost:3000'],
50
+ baseURL: config.baseURL || 'http://localhost:3000',
51
+ secret: config.secret,
52
+ emailAndPassword: {
53
+ enabled: true,
54
+ requireEmailVerification: false,
55
+ },
56
+ advanced: {
57
+ cookies: {
58
+ session_token: {
59
+ name: 'refreshToken',
60
+ attributes: {
61
+ httpOnly: true,
62
+ secure: config.baseURL?.includes('localhost') || config.baseURL?.includes('127.0.0.1')
63
+ ? false
64
+ : true,
65
+ },
66
+ },
67
+ },
68
+ },
69
+ basePath: '/auth/better-auth',
70
+ };
71
+ return betterAuth(authConfig);
72
+ }
@@ -0,0 +1,15 @@
1
+ export { BetterAuthProvider } from './providers/better-auth-provider.js';
2
+ export { createBetterAuthConfig } from './auth/auth-config.js';
3
+ export { createDatabaseAdapter, createSqliteAdapter, createMysqlAdapter, getIdpSqliteDatabasePath, } from './adapters/database.js';
4
+ export { TemplateService } from './services/template-service.js';
5
+ export { MagicLinkService } from './services/magic-link-service.js';
6
+ export { PageService } from './services/page-service.js';
7
+ export { AuthenticationService } from './services/authentication-service.js';
8
+ export { TokenService } from './services/token-service.js';
9
+ export { UserManagementService } from './services/user-management-service.js';
10
+ export { DatabaseService } from './services/database-service.js';
11
+ export { RequestHandlerService } from './services/request-handler-service.js';
12
+ export { MiddlewareService } from './services/middleware-service.js';
13
+ export { CryptoService } from './services/crypto-service.js';
14
+ export type { BetterAuthConfig, DatabaseConfig, SqliteConfig, MySqlConfig, CustomDatabaseConfig, } from './types/index.js';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AACzE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAG/D,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAG7D,YAAY,EACV,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,WAAW,EACX,oBAAoB,GACrB,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ // Main Better Auth exports
2
+ export { BetterAuthProvider } from './providers/better-auth-provider.js';
3
+ export { createBetterAuthConfig } from './auth/auth-config.js';
4
+ // Database adapters
5
+ export { createDatabaseAdapter, createSqliteAdapter, createMysqlAdapter, getIdpSqliteDatabasePath, } from './adapters/database.js';
6
+ // Services
7
+ export { TemplateService } from './services/template-service.js';
8
+ export { MagicLinkService } from './services/magic-link-service.js';
9
+ export { PageService } from './services/page-service.js';
10
+ export { AuthenticationService } from './services/authentication-service.js';
11
+ export { TokenService } from './services/token-service.js';
12
+ export { UserManagementService } from './services/user-management-service.js';
13
+ export { DatabaseService } from './services/database-service.js';
14
+ export { RequestHandlerService } from './services/request-handler-service.js';
15
+ export { MiddlewareService } from './services/middleware-service.js';
16
+ export { CryptoService } from './services/crypto-service.js';
@@ -0,0 +1,34 @@
1
+ import { AuthResult, AddUserCommandResponse, IdpProviderAddUserCommand, IdpProviderListUsersCommand, IdpProviderRemoveUserCommand, IdpProvider, Payload } from '@owox/idp-protocol';
2
+ import { betterAuth } from 'better-auth';
3
+ import { Express, type Request, Response, NextFunction } from 'express';
4
+ import { BetterAuthConfig } from '../types/index.js';
5
+ export declare class BetterAuthProvider implements IdpProvider, IdpProviderAddUserCommand, IdpProviderListUsersCommand, IdpProviderRemoveUserCommand {
6
+ private readonly auth;
7
+ private readonly authenticationService;
8
+ private readonly tokenService;
9
+ private readonly userManagementService;
10
+ private readonly databaseService;
11
+ private readonly requestHandlerService;
12
+ private readonly middlewareService;
13
+ private readonly pageService;
14
+ private constructor();
15
+ getAuth(): Awaited<ReturnType<typeof betterAuth>>;
16
+ static create(config: BetterAuthConfig): Promise<BetterAuthProvider>;
17
+ getBetterAuth(): Awaited<ReturnType<typeof betterAuth>>;
18
+ registerRoutes(app: Express): void;
19
+ signInMiddleware(req: Request, res: Response, next: NextFunction): Promise<void | Response>;
20
+ signOutMiddleware(req: Request, res: Response, next: NextFunction): Promise<void | Response>;
21
+ accessTokenMiddleware(req: Request, res: Response, next: NextFunction): Promise<void | Response>;
22
+ userApiMiddleware(req: Request, res: Response, next: NextFunction): Promise<Response<Payload>>;
23
+ initialize(): Promise<void>;
24
+ introspectToken(token: string): Promise<Payload | null>;
25
+ parseToken(token: string): Promise<Payload | null>;
26
+ verifyToken(token: string): Promise<Payload | null>;
27
+ refreshToken(refreshToken: string): Promise<AuthResult>;
28
+ revokeToken(token: string): Promise<void>;
29
+ shutdown(): Promise<void>;
30
+ addUser(username: string, _password?: string): Promise<AddUserCommandResponse>;
31
+ listUsers(): Promise<Payload[]>;
32
+ removeUser(userId: string): Promise<void>;
33
+ }
34
+ //# sourceMappingURL=better-auth-provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"better-auth-provider.d.ts","sourceRoot":"","sources":["../../src/providers/better-auth-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,sBAAsB,EACtB,yBAAyB,EACzB,2BAA2B,EAC3B,4BAA4B,EAC5B,WAAW,EACX,OAAO,EACR,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,KAAK,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAExE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAYrD,qBAAa,kBACX,YACE,WAAW,EACX,yBAAyB,EACzB,2BAA2B,EAC3B,4BAA4B;IAWV,OAAO,CAAC,QAAQ,CAAC,IAAI;IARzC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAwB;IAC9D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAwB;IAC9D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAkB;IAClD,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAwB;IAC9D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAoB;IACtD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAE1C,OAAO;IA0BP,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;WAIpC,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAK1E,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;IAIvD,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAe5B,gBAAgB,CACpB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC;IAIrB,iBAAiB,CACrB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC;IAIrB,qBAAqB,CACzB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC;IAIrB,iBAAiB,CACrB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAIvB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAIvD,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAIlD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;IAInD,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAIvD,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIzC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAI9E,SAAS,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAI/B,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGhD"}
@@ -0,0 +1,99 @@
1
+ import express from 'express';
2
+ import { createBetterAuthConfig } from '../auth/auth-config.js';
3
+ import { MagicLinkService } from '../services/magic-link-service.js';
4
+ import { CryptoService } from '../services/crypto-service.js';
5
+ import { AuthenticationService } from '../services/authentication-service.js';
6
+ import { TokenService } from '../services/token-service.js';
7
+ import { UserManagementService } from '../services/user-management-service.js';
8
+ import { DatabaseService } from '../services/database-service.js';
9
+ import { RequestHandlerService } from '../services/request-handler-service.js';
10
+ import { MiddlewareService } from '../services/middleware-service.js';
11
+ import { PageService } from '../services/page-service.js';
12
+ export class BetterAuthProvider {
13
+ auth;
14
+ // Services
15
+ authenticationService;
16
+ tokenService;
17
+ userManagementService;
18
+ databaseService;
19
+ requestHandlerService;
20
+ middlewareService;
21
+ pageService;
22
+ constructor(auth) {
23
+ this.auth = auth;
24
+ // Initialize core services
25
+ const cryptoService = new CryptoService(this.auth);
26
+ const magicLinkService = new MagicLinkService(this.auth, cryptoService);
27
+ // Initialize all business logic services
28
+ this.authenticationService = new AuthenticationService(this.auth, cryptoService);
29
+ this.tokenService = new TokenService(this.auth, cryptoService);
30
+ this.userManagementService = new UserManagementService(this.auth, magicLinkService, cryptoService);
31
+ this.databaseService = new DatabaseService(this.auth);
32
+ this.requestHandlerService = new RequestHandlerService(this.auth);
33
+ this.pageService = new PageService(this.authenticationService, this.userManagementService, cryptoService);
34
+ this.middlewareService = new MiddlewareService(this.authenticationService, this.pageService);
35
+ // Set circular dependency
36
+ this.authenticationService.setUserManagementService(this.userManagementService);
37
+ }
38
+ getAuth() {
39
+ return this.auth;
40
+ }
41
+ static async create(config) {
42
+ const auth = await createBetterAuthConfig(config);
43
+ return new BetterAuthProvider(auth);
44
+ }
45
+ getBetterAuth() {
46
+ return this.auth;
47
+ }
48
+ registerRoutes(app) {
49
+ // Setup middleware
50
+ app.use(express.json()); // Add JSON parsing middleware
51
+ app.use(express.urlencoded({ extended: true }));
52
+ // Setup Better Auth handler
53
+ this.requestHandlerService.setupBetterAuthHandler(app);
54
+ this.pageService.registerRoutes(app);
55
+ app.post('/auth/api/sign-in', this.authenticationService.signInMiddleware.bind(this.authenticationService));
56
+ }
57
+ async signInMiddleware(req, res, next) {
58
+ return this.middlewareService.signInMiddleware(req, res, next);
59
+ }
60
+ async signOutMiddleware(req, res, next) {
61
+ return this.middlewareService.signOutMiddleware(req, res, next);
62
+ }
63
+ async accessTokenMiddleware(req, res, next) {
64
+ return this.middlewareService.accessTokenMiddleware(req, res, next);
65
+ }
66
+ async userApiMiddleware(req, res, next) {
67
+ return this.middlewareService.userApiMiddleware(req, res, next);
68
+ }
69
+ async initialize() {
70
+ await this.databaseService.runMigrations();
71
+ }
72
+ async introspectToken(token) {
73
+ return this.tokenService.introspectToken(token);
74
+ }
75
+ async parseToken(token) {
76
+ return this.tokenService.parseToken(token);
77
+ }
78
+ async verifyToken(token) {
79
+ return this.tokenService.verifyToken(token);
80
+ }
81
+ async refreshToken(refreshToken) {
82
+ return this.tokenService.refreshToken(refreshToken);
83
+ }
84
+ async revokeToken(token) {
85
+ return this.tokenService.revokeToken(token);
86
+ }
87
+ async shutdown() {
88
+ return Promise.resolve();
89
+ }
90
+ async addUser(username, _password) {
91
+ return this.userManagementService.addUserViaMagicLink(username);
92
+ }
93
+ async listUsers() {
94
+ return this.userManagementService.listUsers();
95
+ }
96
+ async removeUser(userId) {
97
+ return this.userManagementService.removeUser(userId);
98
+ }
99
+ }
@@ -0,0 +1,23 @@
1
+ import { createBetterAuthConfig } from '../auth/auth-config.js';
2
+ import { CryptoService } from './crypto-service.js';
3
+ import { AuthSession, SessionValidationResult } from '../types/auth-session.js';
4
+ import { type Request, type Response, type NextFunction } from 'express';
5
+ import type { UserManagementService } from './user-management-service.js';
6
+ export declare class AuthenticationService {
7
+ private readonly auth;
8
+ private readonly cryptoService;
9
+ private userManagementService?;
10
+ constructor(auth: Awaited<ReturnType<typeof createBetterAuthConfig>>, cryptoService: CryptoService);
11
+ setUserManagementService(userManagementService: UserManagementService): void;
12
+ getSession(req: Request): Promise<AuthSession | null>;
13
+ signIn(email: string, password: string, protocol: string, host: string): Promise<globalThis.Response>;
14
+ signOut(req: Request): Promise<void>;
15
+ generateAccessToken(req: Request): Promise<string>;
16
+ validateSession(req: Request): Promise<SessionValidationResult>;
17
+ signInMiddleware(req: Request, res: Response, _next: NextFunction): Promise<void | Response>;
18
+ signOutMiddleware(req: Request, res: Response, _next: NextFunction): Promise<void | Response>;
19
+ accessTokenMiddleware(req: Request, res: Response, _next: NextFunction): Promise<void | Response>;
20
+ setPassword(password: string, req: Request): Promise<unknown>;
21
+ requireAuthMiddleware(req: Request, res: Response, next: NextFunction): Promise<void | Response>;
22
+ }
23
+ //# sourceMappingURL=authentication-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"authentication-service.d.ts","sourceRoot":"","sources":["../../src/services/authentication-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAChF,OAAO,EAAE,KAAK,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAC;AAE1E,qBAAa,qBAAqB;IAI9B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAJhC,OAAO,CAAC,qBAAqB,CAAC,CAAwB;gBAGnC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,sBAAsB,CAAC,CAAC,EACxD,aAAa,EAAE,aAAa;IAG/C,wBAAwB,CAAC,qBAAqB,EAAE,qBAAqB,GAAG,IAAI;IAItE,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;IA6BrD,MAAM,CACV,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC;IAoBzB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAWpC,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAyBlD,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAuB/D,gBAAgB,CACpB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC;IAmCrB,iBAAiB,CACrB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC;IAgBrB,qBAAqB,CACzB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,YAAY,GAClB,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC;IAiBrB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAqB7D,qBAAqB,CACzB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,QAAQ,EACb,IAAI,EAAE,YAAY,GACjB,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC;CAe5B"}