@qwickapps/server 1.3.0 → 1.4.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 (241) hide show
  1. package/README.md +311 -0
  2. package/dist/core/control-panel.d.ts.map +1 -1
  3. package/dist/core/control-panel.js +144 -2
  4. package/dist/core/control-panel.js.map +1 -1
  5. package/dist/core/plugin-registry.d.ts +36 -0
  6. package/dist/core/plugin-registry.d.ts.map +1 -1
  7. package/dist/core/plugin-registry.js +26 -0
  8. package/dist/core/plugin-registry.js.map +1 -1
  9. package/dist/core/types.d.ts +19 -0
  10. package/dist/core/types.d.ts.map +1 -1
  11. package/dist/index.d.ts +2 -2
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +4 -2
  14. package/dist/index.js.map +1 -1
  15. package/dist/plugins/auth/adapter-wrapper.d.ts +47 -0
  16. package/dist/plugins/auth/adapter-wrapper.d.ts.map +1 -0
  17. package/dist/plugins/auth/adapter-wrapper.js +166 -0
  18. package/dist/plugins/auth/adapter-wrapper.js.map +1 -0
  19. package/dist/plugins/auth/adapter-wrapper.test.d.ts +7 -0
  20. package/dist/plugins/auth/adapter-wrapper.test.d.ts.map +1 -0
  21. package/dist/plugins/auth/adapter-wrapper.test.js +303 -0
  22. package/dist/plugins/auth/adapter-wrapper.test.js.map +1 -0
  23. package/dist/plugins/auth/adapters/index.d.ts +1 -0
  24. package/dist/plugins/auth/adapters/index.d.ts.map +1 -1
  25. package/dist/plugins/auth/adapters/index.js +1 -0
  26. package/dist/plugins/auth/adapters/index.js.map +1 -1
  27. package/dist/plugins/auth/adapters/supabase-adapter.d.ts.map +1 -1
  28. package/dist/plugins/auth/adapters/supabase-adapter.js.map +1 -1
  29. package/dist/plugins/auth/adapters/supertokens-adapter.d.ts +18 -0
  30. package/dist/plugins/auth/adapters/supertokens-adapter.d.ts.map +1 -0
  31. package/dist/plugins/auth/adapters/supertokens-adapter.js +267 -0
  32. package/dist/plugins/auth/adapters/supertokens-adapter.js.map +1 -0
  33. package/dist/plugins/auth/config-store.d.ts +11 -0
  34. package/dist/plugins/auth/config-store.d.ts.map +1 -0
  35. package/dist/plugins/auth/config-store.js +232 -0
  36. package/dist/plugins/auth/config-store.js.map +1 -0
  37. package/dist/plugins/auth/config-store.test.d.ts +7 -0
  38. package/dist/plugins/auth/config-store.test.d.ts.map +1 -0
  39. package/dist/plugins/auth/config-store.test.js +299 -0
  40. package/dist/plugins/auth/config-store.test.js.map +1 -0
  41. package/dist/plugins/auth/env-config.d.ts +138 -0
  42. package/dist/plugins/auth/env-config.d.ts.map +1 -0
  43. package/dist/plugins/auth/env-config.js +1122 -0
  44. package/dist/plugins/auth/env-config.js.map +1 -0
  45. package/dist/plugins/auth/index.d.ts +7 -1
  46. package/dist/plugins/auth/index.d.ts.map +1 -1
  47. package/dist/plugins/auth/index.js +7 -0
  48. package/dist/plugins/auth/index.js.map +1 -1
  49. package/dist/plugins/auth/supertokens-adapter.test.d.ts +10 -0
  50. package/dist/plugins/auth/supertokens-adapter.test.d.ts.map +1 -0
  51. package/dist/plugins/auth/supertokens-adapter.test.js +486 -0
  52. package/dist/plugins/auth/supertokens-adapter.test.js.map +1 -0
  53. package/dist/plugins/auth/types.d.ts +176 -0
  54. package/dist/plugins/auth/types.d.ts.map +1 -1
  55. package/dist/plugins/auth/types.js.map +1 -1
  56. package/dist/plugins/cache-plugin.test.js +3 -0
  57. package/dist/plugins/cache-plugin.test.js.map +1 -1
  58. package/dist/plugins/index.d.ts +6 -2
  59. package/dist/plugins/index.d.ts.map +1 -1
  60. package/dist/plugins/index.js +5 -1
  61. package/dist/plugins/index.js.map +1 -1
  62. package/dist/plugins/postgres-plugin.test.js +3 -0
  63. package/dist/plugins/postgres-plugin.test.js.map +1 -1
  64. package/dist/plugins/preferences/__tests__/deep-merge.test.d.ts +7 -0
  65. package/dist/plugins/preferences/__tests__/deep-merge.test.d.ts.map +1 -0
  66. package/dist/plugins/preferences/__tests__/deep-merge.test.js +215 -0
  67. package/dist/plugins/preferences/__tests__/deep-merge.test.js.map +1 -0
  68. package/dist/plugins/preferences/__tests__/preferences-plugin.test.d.ts +7 -0
  69. package/dist/plugins/preferences/__tests__/preferences-plugin.test.d.ts.map +1 -0
  70. package/dist/plugins/preferences/__tests__/preferences-plugin.test.js +265 -0
  71. package/dist/plugins/preferences/__tests__/preferences-plugin.test.js.map +1 -0
  72. package/dist/plugins/preferences/index.d.ts +12 -0
  73. package/dist/plugins/preferences/index.d.ts.map +1 -0
  74. package/dist/plugins/preferences/index.js +13 -0
  75. package/dist/plugins/preferences/index.js.map +1 -0
  76. package/dist/plugins/preferences/preferences-plugin.d.ts +39 -0
  77. package/dist/plugins/preferences/preferences-plugin.d.ts.map +1 -0
  78. package/dist/plugins/preferences/preferences-plugin.js +226 -0
  79. package/dist/plugins/preferences/preferences-plugin.js.map +1 -0
  80. package/dist/plugins/preferences/stores/index.d.ts +9 -0
  81. package/dist/plugins/preferences/stores/index.d.ts.map +1 -0
  82. package/dist/plugins/preferences/stores/index.js +9 -0
  83. package/dist/plugins/preferences/stores/index.js.map +1 -0
  84. package/dist/plugins/preferences/stores/postgres-store.d.ts +41 -0
  85. package/dist/plugins/preferences/stores/postgres-store.d.ts.map +1 -0
  86. package/dist/plugins/preferences/stores/postgres-store.js +181 -0
  87. package/dist/plugins/preferences/stores/postgres-store.js.map +1 -0
  88. package/dist/plugins/preferences/types.d.ts +91 -0
  89. package/dist/plugins/preferences/types.d.ts.map +1 -0
  90. package/dist/plugins/preferences/types.js +10 -0
  91. package/dist/plugins/preferences/types.js.map +1 -0
  92. package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.d.ts +7 -0
  93. package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.d.ts.map +1 -0
  94. package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.js +220 -0
  95. package/dist/plugins/rate-limit/__tests__/rate-limit-plugin.test.js.map +1 -0
  96. package/dist/plugins/rate-limit/cleanup.d.ts +40 -0
  97. package/dist/plugins/rate-limit/cleanup.d.ts.map +1 -0
  98. package/dist/plugins/rate-limit/cleanup.js +72 -0
  99. package/dist/plugins/rate-limit/cleanup.js.map +1 -0
  100. package/dist/plugins/rate-limit/env-config.d.ts +91 -0
  101. package/dist/plugins/rate-limit/env-config.d.ts.map +1 -0
  102. package/dist/plugins/rate-limit/env-config.js +318 -0
  103. package/dist/plugins/rate-limit/env-config.js.map +1 -0
  104. package/dist/plugins/rate-limit/index.d.ts +76 -0
  105. package/dist/plugins/rate-limit/index.d.ts.map +1 -0
  106. package/dist/plugins/rate-limit/index.js +79 -0
  107. package/dist/plugins/rate-limit/index.js.map +1 -0
  108. package/dist/plugins/rate-limit/middleware.d.ts +40 -0
  109. package/dist/plugins/rate-limit/middleware.d.ts.map +1 -0
  110. package/dist/plugins/rate-limit/middleware.js +169 -0
  111. package/dist/plugins/rate-limit/middleware.js.map +1 -0
  112. package/dist/plugins/rate-limit/rate-limit-plugin.d.ts +44 -0
  113. package/dist/plugins/rate-limit/rate-limit-plugin.d.ts.map +1 -0
  114. package/dist/plugins/rate-limit/rate-limit-plugin.js +354 -0
  115. package/dist/plugins/rate-limit/rate-limit-plugin.js.map +1 -0
  116. package/dist/plugins/rate-limit/rate-limit-service.d.ts +110 -0
  117. package/dist/plugins/rate-limit/rate-limit-service.d.ts.map +1 -0
  118. package/dist/plugins/rate-limit/rate-limit-service.js +172 -0
  119. package/dist/plugins/rate-limit/rate-limit-service.js.map +1 -0
  120. package/dist/plugins/rate-limit/stores/cache-store.d.ts +33 -0
  121. package/dist/plugins/rate-limit/stores/cache-store.d.ts.map +1 -0
  122. package/dist/plugins/rate-limit/stores/cache-store.js +225 -0
  123. package/dist/plugins/rate-limit/stores/cache-store.js.map +1 -0
  124. package/dist/plugins/rate-limit/stores/index.d.ts +8 -0
  125. package/dist/plugins/rate-limit/stores/index.d.ts.map +1 -0
  126. package/dist/plugins/rate-limit/stores/index.js +8 -0
  127. package/dist/plugins/rate-limit/stores/index.js.map +1 -0
  128. package/dist/plugins/rate-limit/stores/postgres-store.d.ts +34 -0
  129. package/dist/plugins/rate-limit/stores/postgres-store.d.ts.map +1 -0
  130. package/dist/plugins/rate-limit/stores/postgres-store.js +320 -0
  131. package/dist/plugins/rate-limit/stores/postgres-store.js.map +1 -0
  132. package/dist/plugins/rate-limit/strategies/fixed-window.d.ts +21 -0
  133. package/dist/plugins/rate-limit/strategies/fixed-window.d.ts.map +1 -0
  134. package/dist/plugins/rate-limit/strategies/fixed-window.js +97 -0
  135. package/dist/plugins/rate-limit/strategies/fixed-window.js.map +1 -0
  136. package/dist/plugins/rate-limit/strategies/index.d.ts +14 -0
  137. package/dist/plugins/rate-limit/strategies/index.d.ts.map +1 -0
  138. package/dist/plugins/rate-limit/strategies/index.js +27 -0
  139. package/dist/plugins/rate-limit/strategies/index.js.map +1 -0
  140. package/dist/plugins/rate-limit/strategies/sliding-window.d.ts +22 -0
  141. package/dist/plugins/rate-limit/strategies/sliding-window.d.ts.map +1 -0
  142. package/dist/plugins/rate-limit/strategies/sliding-window.js +122 -0
  143. package/dist/plugins/rate-limit/strategies/sliding-window.js.map +1 -0
  144. package/dist/plugins/rate-limit/strategies/token-bucket.d.ts +28 -0
  145. package/dist/plugins/rate-limit/strategies/token-bucket.d.ts.map +1 -0
  146. package/dist/plugins/rate-limit/strategies/token-bucket.js +121 -0
  147. package/dist/plugins/rate-limit/strategies/token-bucket.js.map +1 -0
  148. package/dist/plugins/rate-limit/types.d.ts +265 -0
  149. package/dist/plugins/rate-limit/types.d.ts.map +1 -0
  150. package/dist/plugins/rate-limit/types.js +9 -0
  151. package/dist/plugins/rate-limit/types.js.map +1 -0
  152. package/dist/plugins/users/__tests__/users-plugin.test.d.ts +9 -0
  153. package/dist/plugins/users/__tests__/users-plugin.test.d.ts.map +1 -0
  154. package/dist/plugins/users/__tests__/users-plugin.test.js +546 -0
  155. package/dist/plugins/users/__tests__/users-plugin.test.js.map +1 -0
  156. package/dist/plugins/users/index.d.ts +2 -2
  157. package/dist/plugins/users/index.d.ts.map +1 -1
  158. package/dist/plugins/users/index.js +1 -1
  159. package/dist/plugins/users/index.js.map +1 -1
  160. package/dist/plugins/users/types.d.ts +36 -0
  161. package/dist/plugins/users/types.d.ts.map +1 -1
  162. package/dist/plugins/users/users-plugin.d.ts +8 -2
  163. package/dist/plugins/users/users-plugin.d.ts.map +1 -1
  164. package/dist/plugins/users/users-plugin.js +122 -5
  165. package/dist/plugins/users/users-plugin.js.map +1 -1
  166. package/dist-ui/assets/index-D7DoZ9rL.js +478 -0
  167. package/dist-ui/assets/index-D7DoZ9rL.js.map +1 -0
  168. package/dist-ui/index.html +1 -1
  169. package/dist-ui-lib/api/controlPanelApi.d.ts +194 -7
  170. package/dist-ui-lib/dashboard/WidgetComponentRegistry.d.ts +9 -5
  171. package/dist-ui-lib/dashboard/builtInWidgets.d.ts +7 -1
  172. package/dist-ui-lib/dashboard/widgets/AuthStatusWidget.d.ts +9 -0
  173. package/dist-ui-lib/dashboard/widgets/IntegrationStatusWidget.d.ts +9 -0
  174. package/dist-ui-lib/dashboard/widgets/index.d.ts +2 -0
  175. package/dist-ui-lib/index.js +3665 -3945
  176. package/dist-ui-lib/index.js.map +1 -1
  177. package/dist-ui-lib/pages/AuthPage.d.ts +1 -0
  178. package/dist-ui-lib/pages/IntegrationsPage.d.ts +1 -0
  179. package/dist-ui-lib/pages/PluginsPage.d.ts +1 -0
  180. package/dist-ui-lib/pages/RateLimitPage.d.ts +1 -0
  181. package/package.json +7 -2
  182. package/src/core/control-panel.ts +161 -2
  183. package/src/core/plugin-registry.ts +63 -0
  184. package/src/core/types.ts +17 -0
  185. package/src/index.ts +45 -0
  186. package/src/plugins/auth/adapter-wrapper.test.ts +395 -0
  187. package/src/plugins/auth/adapter-wrapper.ts +205 -0
  188. package/src/plugins/auth/adapters/index.ts +1 -0
  189. package/src/plugins/auth/adapters/supabase-adapter.ts +22 -14
  190. package/src/plugins/auth/adapters/supertokens-adapter.ts +326 -0
  191. package/src/plugins/auth/config-store.test.ts +417 -0
  192. package/src/plugins/auth/config-store.ts +305 -0
  193. package/src/plugins/auth/env-config.ts +1279 -0
  194. package/src/plugins/auth/index.ts +30 -0
  195. package/src/plugins/auth/supertokens-adapter.test.ts +621 -0
  196. package/src/plugins/auth/types.ts +218 -0
  197. package/src/plugins/cache-plugin.test.ts +3 -0
  198. package/src/plugins/index.ts +75 -0
  199. package/src/plugins/postgres-plugin.test.ts +3 -0
  200. package/src/plugins/preferences/__tests__/deep-merge.test.ts +242 -0
  201. package/src/plugins/preferences/__tests__/preferences-plugin.test.ts +350 -0
  202. package/src/plugins/preferences/index.ts +30 -0
  203. package/src/plugins/preferences/preferences-plugin.ts +270 -0
  204. package/src/plugins/preferences/stores/index.ts +9 -0
  205. package/src/plugins/preferences/stores/postgres-store.ts +252 -0
  206. package/src/plugins/preferences/types.ts +100 -0
  207. package/src/plugins/rate-limit/__tests__/rate-limit-plugin.test.ts +259 -0
  208. package/src/plugins/rate-limit/cleanup.ts +117 -0
  209. package/src/plugins/rate-limit/env-config.ts +400 -0
  210. package/src/plugins/rate-limit/index.ts +128 -0
  211. package/src/plugins/rate-limit/middleware.ts +212 -0
  212. package/src/plugins/rate-limit/rate-limit-plugin.ts +400 -0
  213. package/src/plugins/rate-limit/rate-limit-service.ts +228 -0
  214. package/src/plugins/rate-limit/stores/cache-store.ts +261 -0
  215. package/src/plugins/rate-limit/stores/index.ts +8 -0
  216. package/src/plugins/rate-limit/stores/postgres-store.ts +402 -0
  217. package/src/plugins/rate-limit/strategies/fixed-window.ts +116 -0
  218. package/src/plugins/rate-limit/strategies/index.ts +30 -0
  219. package/src/plugins/rate-limit/strategies/sliding-window.ts +157 -0
  220. package/src/plugins/rate-limit/strategies/token-bucket.ts +154 -0
  221. package/src/plugins/rate-limit/types.ts +338 -0
  222. package/src/plugins/users/__tests__/users-plugin.test.ts +690 -0
  223. package/src/plugins/users/index.ts +3 -0
  224. package/src/plugins/users/types.ts +38 -0
  225. package/src/plugins/users/users-plugin.ts +142 -5
  226. package/ui/src/App.tsx +35 -14
  227. package/ui/src/api/controlPanelApi.ts +326 -1
  228. package/ui/src/components/ControlPanelApp.tsx +3 -0
  229. package/ui/src/dashboard/PluginWidgetRenderer.tsx +13 -10
  230. package/ui/src/dashboard/WidgetComponentRegistry.tsx +13 -9
  231. package/ui/src/dashboard/builtInWidgets.tsx +13 -3
  232. package/ui/src/dashboard/widgets/AuthStatusWidget.tsx +143 -0
  233. package/ui/src/dashboard/widgets/IntegrationStatusWidget.tsx +135 -0
  234. package/ui/src/dashboard/widgets/index.ts +2 -0
  235. package/ui/src/pages/AuthPage.tsx +1103 -0
  236. package/ui/src/pages/IntegrationsPage.tsx +288 -0
  237. package/ui/src/pages/PluginsPage.tsx +394 -0
  238. package/ui/src/pages/RateLimitPage.tsx +292 -0
  239. package/ui/vite.lib.config.ts +5 -0
  240. package/dist-ui/assets/index-Bsp2ntcw.js +0 -465
  241. package/dist-ui/assets/index-Bsp2ntcw.js.map +0 -1
@@ -0,0 +1,299 @@
1
+ /**
2
+ * Auth Config Store Tests
3
+ *
4
+ * Unit tests for PostgreSQL-backed auth configuration store.
5
+ */
6
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
7
+ import { postgresAuthConfigStore } from './config-store.js';
8
+ function createMockPool() {
9
+ const mockClient = {
10
+ query: vi.fn().mockResolvedValue({ rows: [], rowCount: 0 }),
11
+ on: vi.fn(),
12
+ release: vi.fn(),
13
+ };
14
+ return {
15
+ query: vi.fn().mockResolvedValue({ rows: [], rowCount: 0 }),
16
+ connect: vi.fn().mockResolvedValue(mockClient),
17
+ on: vi.fn(),
18
+ };
19
+ }
20
+ describe('postgresAuthConfigStore', () => {
21
+ let mockPool;
22
+ beforeEach(() => {
23
+ mockPool = createMockPool();
24
+ });
25
+ afterEach(() => {
26
+ vi.clearAllMocks();
27
+ });
28
+ describe('identifier validation', () => {
29
+ it('should reject invalid table names', () => {
30
+ expect(() => postgresAuthConfigStore({
31
+ pool: mockPool,
32
+ tableName: 'DROP TABLE users;--',
33
+ })).toThrow('Invalid table name');
34
+ });
35
+ it('should reject table names with spaces', () => {
36
+ expect(() => postgresAuthConfigStore({
37
+ pool: mockPool,
38
+ tableName: 'my table',
39
+ })).toThrow('Invalid table name');
40
+ });
41
+ it('should reject table names starting with numbers', () => {
42
+ expect(() => postgresAuthConfigStore({
43
+ pool: mockPool,
44
+ tableName: '123table',
45
+ })).toThrow('Invalid table name');
46
+ });
47
+ it('should reject table names longer than 63 characters', () => {
48
+ const longName = 'a'.repeat(64);
49
+ expect(() => postgresAuthConfigStore({
50
+ pool: mockPool,
51
+ tableName: longName,
52
+ })).toThrow('Invalid table name');
53
+ });
54
+ it('should accept valid table names', () => {
55
+ expect(() => postgresAuthConfigStore({
56
+ pool: mockPool,
57
+ tableName: 'auth_config',
58
+ })).not.toThrow();
59
+ });
60
+ it('should accept table names with underscores', () => {
61
+ expect(() => postgresAuthConfigStore({
62
+ pool: mockPool,
63
+ tableName: '_my_auth_config_table',
64
+ })).not.toThrow();
65
+ });
66
+ it('should reject invalid schema names', () => {
67
+ expect(() => postgresAuthConfigStore({
68
+ pool: mockPool,
69
+ schema: 'public; DROP TABLE users;--',
70
+ })).toThrow('Invalid schema name');
71
+ });
72
+ it('should reject invalid notify channel names', () => {
73
+ expect(() => postgresAuthConfigStore({
74
+ pool: mockPool,
75
+ notifyChannel: 'channel-with-dashes',
76
+ })).toThrow('Invalid notify channel');
77
+ });
78
+ });
79
+ describe('initialize', () => {
80
+ it('should create table if autoCreateTable is true', async () => {
81
+ const store = postgresAuthConfigStore({
82
+ pool: mockPool,
83
+ autoCreateTable: true,
84
+ enableNotify: false,
85
+ });
86
+ await store.initialize();
87
+ expect(mockPool.query).toHaveBeenCalledWith(expect.stringContaining('CREATE TABLE IF NOT EXISTS'));
88
+ });
89
+ it('should not create table if autoCreateTable is false', async () => {
90
+ const store = postgresAuthConfigStore({
91
+ pool: mockPool,
92
+ autoCreateTable: false,
93
+ enableNotify: false,
94
+ });
95
+ await store.initialize();
96
+ expect(mockPool.query).not.toHaveBeenCalledWith(expect.stringContaining('CREATE TABLE IF NOT EXISTS'));
97
+ });
98
+ it('should use custom table name', async () => {
99
+ const store = postgresAuthConfigStore({
100
+ pool: mockPool,
101
+ tableName: 'custom_auth_config',
102
+ autoCreateTable: true,
103
+ enableNotify: false,
104
+ });
105
+ await store.initialize();
106
+ expect(mockPool.query).toHaveBeenCalledWith(expect.stringContaining('"public"."custom_auth_config"'));
107
+ });
108
+ it('should use custom schema name', async () => {
109
+ const store = postgresAuthConfigStore({
110
+ pool: mockPool,
111
+ schema: 'myschema',
112
+ autoCreateTable: true,
113
+ enableNotify: false,
114
+ });
115
+ await store.initialize();
116
+ expect(mockPool.query).toHaveBeenCalledWith(expect.stringContaining('"myschema"."auth_config"'));
117
+ });
118
+ });
119
+ describe('load', () => {
120
+ it('should return null when no config exists', async () => {
121
+ mockPool.query.mockResolvedValueOnce({ rows: [], rowCount: 0 });
122
+ const store = postgresAuthConfigStore({
123
+ pool: mockPool,
124
+ autoCreateTable: false,
125
+ enableNotify: false,
126
+ });
127
+ const result = await store.load();
128
+ expect(result).toBeNull();
129
+ });
130
+ it('should return config when it exists', async () => {
131
+ const mockConfig = {
132
+ adapter: 'basic',
133
+ config: { basic: { username: 'admin', password: 'secret' } },
134
+ settings: {},
135
+ updated_at: new Date('2025-01-15T12:00:00Z'),
136
+ updated_by: 'admin@example.com',
137
+ };
138
+ mockPool.query.mockResolvedValueOnce({ rows: [mockConfig], rowCount: 1 });
139
+ const store = postgresAuthConfigStore({
140
+ pool: mockPool,
141
+ autoCreateTable: false,
142
+ enableNotify: false,
143
+ });
144
+ const result = await store.load();
145
+ expect(result).toEqual({
146
+ adapter: 'basic',
147
+ config: { basic: { username: 'admin', password: 'secret' } },
148
+ settings: {},
149
+ updatedAt: '2025-01-15T12:00:00.000Z',
150
+ updatedBy: 'admin@example.com',
151
+ });
152
+ });
153
+ });
154
+ describe('save', () => {
155
+ it('should upsert config to database', async () => {
156
+ const store = postgresAuthConfigStore({
157
+ pool: mockPool,
158
+ autoCreateTable: false,
159
+ enableNotify: false,
160
+ });
161
+ const config = {
162
+ adapter: 'basic',
163
+ config: { basic: { username: 'admin', password: 'secret', realm: 'Test' } },
164
+ settings: {},
165
+ updatedAt: new Date().toISOString(),
166
+ updatedBy: 'admin@example.com',
167
+ };
168
+ await store.save(config);
169
+ expect(mockPool.query).toHaveBeenCalledWith(expect.stringContaining('INSERT INTO'), expect.arrayContaining(['basic', expect.any(String), expect.any(String), 'admin@example.com']));
170
+ });
171
+ it('should send NOTIFY when enableNotify is true', async () => {
172
+ const store = postgresAuthConfigStore({
173
+ pool: mockPool,
174
+ autoCreateTable: false,
175
+ enableNotify: true,
176
+ });
177
+ const config = {
178
+ adapter: 'basic',
179
+ config: { basic: { username: 'admin', password: 'secret', realm: 'Test' } },
180
+ settings: {},
181
+ updatedAt: new Date().toISOString(),
182
+ };
183
+ await store.save(config);
184
+ expect(mockPool.query).toHaveBeenCalledWith('NOTIFY auth_config_changed');
185
+ });
186
+ it('should not send NOTIFY when enableNotify is false', async () => {
187
+ const store = postgresAuthConfigStore({
188
+ pool: mockPool,
189
+ autoCreateTable: false,
190
+ enableNotify: false,
191
+ });
192
+ const config = {
193
+ adapter: 'basic',
194
+ config: { basic: { username: 'admin', password: 'secret', realm: 'Test' } },
195
+ settings: {},
196
+ updatedAt: new Date().toISOString(),
197
+ };
198
+ await store.save(config);
199
+ expect(mockPool.query).not.toHaveBeenCalledWith('NOTIFY auth_config_changed');
200
+ });
201
+ });
202
+ describe('delete', () => {
203
+ it('should delete config from database', async () => {
204
+ mockPool.query.mockResolvedValueOnce({ rows: [], rowCount: 1 });
205
+ const store = postgresAuthConfigStore({
206
+ pool: mockPool,
207
+ autoCreateTable: false,
208
+ enableNotify: false,
209
+ });
210
+ const result = await store.delete();
211
+ expect(mockPool.query).toHaveBeenCalledWith(expect.stringContaining('DELETE FROM'));
212
+ expect(result).toBe(true);
213
+ });
214
+ it('should return false when no config to delete', async () => {
215
+ mockPool.query.mockResolvedValueOnce({ rows: [], rowCount: 0 });
216
+ const store = postgresAuthConfigStore({
217
+ pool: mockPool,
218
+ autoCreateTable: false,
219
+ enableNotify: false,
220
+ });
221
+ const result = await store.delete();
222
+ expect(result).toBe(false);
223
+ });
224
+ it('should send NOTIFY after delete when enableNotify is true', async () => {
225
+ mockPool.query.mockResolvedValueOnce({ rows: [], rowCount: 1 });
226
+ const store = postgresAuthConfigStore({
227
+ pool: mockPool,
228
+ autoCreateTable: false,
229
+ enableNotify: true,
230
+ });
231
+ await store.delete();
232
+ expect(mockPool.query).toHaveBeenCalledWith('NOTIFY auth_config_changed');
233
+ });
234
+ });
235
+ describe('onChange', () => {
236
+ it('should register listener and return unsubscribe function', () => {
237
+ const store = postgresAuthConfigStore({
238
+ pool: mockPool,
239
+ autoCreateTable: false,
240
+ enableNotify: false,
241
+ });
242
+ const listener = vi.fn();
243
+ const unsubscribe = store.onChange(listener);
244
+ expect(typeof unsubscribe).toBe('function');
245
+ });
246
+ it('should unsubscribe listener when called', () => {
247
+ const store = postgresAuthConfigStore({
248
+ pool: mockPool,
249
+ autoCreateTable: false,
250
+ enableNotify: false,
251
+ });
252
+ const listener = vi.fn();
253
+ const unsubscribe = store.onChange(listener);
254
+ // Unsubscribe
255
+ unsubscribe();
256
+ // Listener should not be called anymore
257
+ // (We can't easily test this without exposing internals, but the function exists)
258
+ expect(unsubscribe).toBeDefined();
259
+ });
260
+ });
261
+ describe('lazy pool initialization', () => {
262
+ it('should accept a function that returns the pool', async () => {
263
+ const poolFn = vi.fn().mockReturnValue(mockPool);
264
+ const store = postgresAuthConfigStore({
265
+ pool: poolFn,
266
+ autoCreateTable: false,
267
+ enableNotify: false,
268
+ });
269
+ mockPool.query.mockResolvedValueOnce({ rows: [], rowCount: 0 });
270
+ await store.load();
271
+ expect(poolFn).toHaveBeenCalled();
272
+ });
273
+ it('should throw if pool is invalid', async () => {
274
+ const store = postgresAuthConfigStore({
275
+ pool: (() => ({})),
276
+ autoCreateTable: false,
277
+ enableNotify: false,
278
+ });
279
+ await expect(store.load()).rejects.toThrow('Invalid pool');
280
+ });
281
+ });
282
+ describe('shutdown', () => {
283
+ it('should release listener client and clear listeners', async () => {
284
+ const store = postgresAuthConfigStore({
285
+ pool: mockPool,
286
+ autoCreateTable: false,
287
+ enableNotify: false,
288
+ });
289
+ // Add a listener
290
+ const listener = vi.fn();
291
+ store.onChange(listener);
292
+ // Shutdown
293
+ await store.shutdown();
294
+ // Should complete without error
295
+ expect(true).toBe(true);
296
+ });
297
+ });
298
+ });
299
+ //# sourceMappingURL=config-store.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-store.test.js","sourceRoot":"","sources":["../../../src/plugins/auth/config-store.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Auth Plugin Environment Configuration
3
+ *
4
+ * Factory function and utilities for configuring auth adapters via environment variables.
5
+ * Supports all adapters: Auth0, Supabase, Supertokens, Basic.
6
+ *
7
+ * Copyright (c) 2025 QwickApps.com. All rights reserved.
8
+ */
9
+ import type { Plugin } from '../../core/plugin-registry.js';
10
+ import type { AuthAdapter, Auth0AdapterConfig, SupabaseAdapterConfig, SupertokensAdapterConfig, BasicAdapterConfig, AuthEnvPluginOptions, AuthConfigStatus, AuthAdapterType, RuntimeAuthConfig, TestProviderResponse, AuthConfigStore } from './types.js';
11
+ import { type AdapterWrapper } from './adapter-wrapper.js';
12
+ /**
13
+ * Get an environment variable, treating empty strings as undefined
14
+ */
15
+ declare function getEnv(key: string): string | undefined;
16
+ /**
17
+ * Parse a boolean environment variable
18
+ * Supports: true/false, 1/0, yes/no (case-insensitive)
19
+ */
20
+ declare function getEnvBool(key: string, defaultValue: boolean): boolean;
21
+ /**
22
+ * Parse a comma-separated list environment variable
23
+ */
24
+ declare function getEnvList(key: string): string[] | undefined;
25
+ /**
26
+ * Mask a sensitive value for display
27
+ */
28
+ declare function maskValue(value: string): string;
29
+ interface EnvParseResult<T> {
30
+ config: T | null;
31
+ errors: string[];
32
+ }
33
+ /**
34
+ * Parse Supertokens configuration from environment variables
35
+ */
36
+ declare function parseSupertokensEnv(): EnvParseResult<SupertokensAdapterConfig>;
37
+ /**
38
+ * Parse Auth0 configuration from environment variables
39
+ */
40
+ declare function parseAuth0Env(): EnvParseResult<Auth0AdapterConfig>;
41
+ /**
42
+ * Parse Supabase configuration from environment variables
43
+ */
44
+ declare function parseSupabaseEnv(): EnvParseResult<SupabaseAdapterConfig>;
45
+ /**
46
+ * Parse Basic Auth configuration from environment variables
47
+ */
48
+ declare function parseBasicAuthEnv(): EnvParseResult<BasicAdapterConfig>;
49
+ /**
50
+ * Create an auth plugin configured from environment variables.
51
+ *
52
+ * The plugin state depends on environment configuration:
53
+ * - **disabled**: AUTH_ADAPTER not set - no authentication middleware is applied
54
+ * - **enabled**: Valid configuration - adapter is active and working
55
+ * - **error**: Invalid configuration - plugin is disabled with error details
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * // Zero-config setup - reads everything from env vars
60
+ * const authPlugin = createAuthPluginFromEnv();
61
+ *
62
+ * // With overrides
63
+ * const authPlugin = createAuthPluginFromEnv({
64
+ * excludePaths: ['/health', '/metrics'],
65
+ * authRequired: true,
66
+ * });
67
+ * ```
68
+ *
69
+ * @param options - Optional overrides (env vars take precedence for adapter config)
70
+ * @returns A Plugin instance
71
+ */
72
+ export declare function createAuthPluginFromEnv(options?: AuthEnvPluginOptions): Plugin;
73
+ /**
74
+ * Get current auth plugin status
75
+ */
76
+ export declare function getAuthStatus(): AuthConfigStatus;
77
+ /**
78
+ * Extended options for createAuthPluginFromEnv with runtime config support
79
+ */
80
+ export interface AuthEnvPluginOptionsExtended extends AuthEnvPluginOptions {
81
+ /** Configuration store for runtime config persistence */
82
+ configStore?: AuthConfigStore;
83
+ }
84
+ /**
85
+ * Create an adapter from runtime configuration
86
+ */
87
+ declare function createAdapterFromConfig(adapterType: AuthAdapterType, config: RuntimeAuthConfig['config']): AuthAdapter | null;
88
+ /**
89
+ * Validate adapter configuration
90
+ */
91
+ declare function validateAdapterConfig(adapterType: AuthAdapterType, config: Record<string, unknown>): {
92
+ valid: boolean;
93
+ errors: string[];
94
+ };
95
+ /**
96
+ * Test a provider connection
97
+ */
98
+ declare function testProviderConnection(adapterType: AuthAdapterType, config: Record<string, unknown>): Promise<TestProviderResponse>;
99
+ /**
100
+ * Set the configuration store for runtime auth config persistence.
101
+ *
102
+ * This must be called during application startup to enable runtime configuration
103
+ * features. Without a config store, the PUT/DELETE endpoints will return 503.
104
+ *
105
+ * @param store - PostgreSQL-backed config store from `postgresAuthConfigStore()`
106
+ *
107
+ * @example
108
+ * ```typescript
109
+ * import { Pool } from 'pg';
110
+ * import { setAuthConfigStore, postgresAuthConfigStore } from '@qwickapps/server';
111
+ *
112
+ * const pool = new Pool({ connectionString: process.env.DATABASE_URL });
113
+ * const configStore = postgresAuthConfigStore({ pool });
114
+ * await configStore.initialize();
115
+ * setAuthConfigStore(configStore);
116
+ * ```
117
+ */
118
+ export declare function setAuthConfigStore(store: AuthConfigStore): void;
119
+ /**
120
+ * Get the current adapter wrapper
121
+ */
122
+ export declare function getAdapterWrapper(): AdapterWrapper | null;
123
+ export declare const __testing: {
124
+ parseSupertokensEnv: typeof parseSupertokensEnv;
125
+ parseAuth0Env: typeof parseAuth0Env;
126
+ parseSupabaseEnv: typeof parseSupabaseEnv;
127
+ parseBasicAuthEnv: typeof parseBasicAuthEnv;
128
+ getEnv: typeof getEnv;
129
+ getEnvBool: typeof getEnvBool;
130
+ getEnvList: typeof getEnvList;
131
+ maskValue: typeof maskValue;
132
+ VALID_ADAPTERS: readonly ["supertokens", "auth0", "supabase", "basic"];
133
+ validateAdapterConfig: typeof validateAdapterConfig;
134
+ testProviderConnection: typeof testProviderConnection;
135
+ createAdapterFromConfig: typeof createAdapterFromConfig;
136
+ };
137
+ export {};
138
+ //# sourceMappingURL=env-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-config.d.ts","sourceRoot":"","sources":["../../../src/plugins/auth/env-config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAgC,MAAM,+BAA+B,CAAC;AAC1F,OAAO,KAAK,EAEV,WAAW,EACX,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAEhB,eAAe,EACf,iBAAiB,EAGjB,oBAAoB,EACpB,eAAe,EAChB,MAAM,YAAY,CAAC;AAMpB,OAAO,EAAwB,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAwBjF;;GAEG;AACH,iBAAS,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAM/C;AAED;;;GAGG;AACH,iBAAS,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,OAAO,CAa/D;AAED;;GAEG;AACH,iBAAS,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CASrD;AAED;;GAEG;AACH,iBAAS,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKxC;AAMD,UAAU,cAAc,CAAC,CAAC;IACxB,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;GAEG;AACH,iBAAS,mBAAmB,IAAI,cAAc,CAAC,wBAAwB,CAAC,CAoEvE;AAED;;GAEG;AACH,iBAAS,aAAa,IAAI,cAAc,CAAC,kBAAkB,CAAC,CAwC3D;AAED;;GAEG;AACH,iBAAS,gBAAgB,IAAI,cAAc,CAAC,qBAAqB,CAAC,CAoBjE;AAED;;GAEG;AACH,iBAAS,iBAAiB,IAAI,cAAc,CAAC,kBAAkB,CAAC,CAqB/D;AAYD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,CAAC,EAAE,oBAAoB,GAAG,MAAM,CA0G9E;AAMD;;GAEG;AACH,wBAAgB,aAAa,IAAI,gBAAgB,CAEhD;AA8aD;;GAEG;AACH,MAAM,WAAW,4BAA6B,SAAQ,oBAAoB;IACxE,yDAAyD;IACzD,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED;;GAEG;AACH,iBAAS,uBAAuB,CAC9B,WAAW,EAAE,eAAe,EAC5B,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,GAClC,WAAW,GAAG,IAAI,CAwBpB;AAED;;GAEG;AACH,iBAAS,qBAAqB,CAC5B,WAAW,EAAE,eAAe,EAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CA4BtC;AA4BD;;GAEG;AACH,iBAAe,sBAAsB,CACnC,WAAW,EAAE,eAAe,EAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,oBAAoB,CAAC,CA2I/B;AAkHD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAE/D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,cAAc,GAAG,IAAI,CAEzD;AAOD,eAAO,MAAM,SAAS;;;;;;;;;;;;;CAarB,CAAC"}