@qwickapps/server 1.8.2 → 1.10.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 (71) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +4 -4
  3. package/dist/src/core/control-panel.d.ts.map +1 -1
  4. package/dist/src/core/control-panel.js +2 -1
  5. package/dist/src/core/control-panel.js.map +1 -1
  6. package/dist/src/core/gateway.d.ts.map +1 -1
  7. package/dist/src/core/gateway.js +25 -26
  8. package/dist/src/core/gateway.js.map +1 -1
  9. package/dist/src/plugins/auth/adapters/supertokens-adapter.d.ts.map +1 -1
  10. package/dist/src/plugins/auth/adapters/supertokens-adapter.js +50 -11
  11. package/dist/src/plugins/auth/adapters/supertokens-adapter.js.map +1 -1
  12. package/dist/src/plugins/auth/auth-plugin.d.ts.map +1 -1
  13. package/dist/src/plugins/auth/auth-plugin.js +6 -5
  14. package/dist/src/plugins/auth/auth-plugin.js.map +1 -1
  15. package/dist/src/plugins/auth/env-config.d.ts.map +1 -1
  16. package/dist/src/plugins/auth/env-config.js +4 -0
  17. package/dist/src/plugins/auth/env-config.js.map +1 -1
  18. package/dist/src/plugins/auth/types.d.ts +8 -0
  19. package/dist/src/plugins/auth/types.d.ts.map +1 -1
  20. package/dist/src/plugins/auth/types.js.map +1 -1
  21. package/dist/src/plugins/maintenance/seed-executor.d.ts.map +1 -1
  22. package/dist/src/plugins/maintenance/seed-executor.js +5 -4
  23. package/dist/src/plugins/maintenance/seed-executor.js.map +1 -1
  24. package/dist/src/plugins/maintenance-plugin.d.ts.map +1 -1
  25. package/dist/src/plugins/maintenance-plugin.js +26 -4
  26. package/dist/src/plugins/maintenance-plugin.js.map +1 -1
  27. package/dist/src/plugins/postgres-plugin.d.ts +17 -0
  28. package/dist/src/plugins/postgres-plugin.d.ts.map +1 -1
  29. package/dist/src/plugins/postgres-plugin.js +36 -11
  30. package/dist/src/plugins/postgres-plugin.js.map +1 -1
  31. package/dist/src/plugins/rate-limit/env-config.d.ts +1 -1
  32. package/dist/src/plugins/rate-limit/env-config.js +4 -4
  33. package/dist/src/plugins/rate-limit/env-config.js.map +1 -1
  34. package/dist/src/utils/index.d.ts +2 -0
  35. package/dist/src/utils/index.d.ts.map +1 -0
  36. package/dist/src/utils/index.js +2 -0
  37. package/dist/src/utils/index.js.map +1 -0
  38. package/dist/src/utils/url.d.ts +9 -0
  39. package/dist/src/utils/url.d.ts.map +1 -0
  40. package/dist/src/utils/url.js +25 -0
  41. package/dist/src/utils/url.js.map +1 -0
  42. package/dist/ui/src/dashboard/widgets/AuthStatusWidget.d.ts.map +1 -1
  43. package/dist/ui/src/dashboard/widgets/AuthStatusWidget.js +1 -1
  44. package/dist/ui/src/dashboard/widgets/AuthStatusWidget.js.map +1 -1
  45. package/dist/ui/src/dashboard/widgets/DatabaseOperationsWidget.d.ts.map +1 -1
  46. package/dist/ui/src/dashboard/widgets/DatabaseOperationsWidget.js +1 -1
  47. package/dist/ui/src/dashboard/widgets/DatabaseOperationsWidget.js.map +1 -1
  48. package/dist-ui/assets/{index-De-dCl_t.css → index-BB_TF4Cq.css} +1 -1
  49. package/dist-ui/assets/index-BdwcYEzG.js +532 -0
  50. package/dist-ui/assets/{index-Cez_jyhl.js.map → index-BdwcYEzG.js.map} +1 -1
  51. package/dist-ui/index.html +2 -2
  52. package/dist-ui-lib/index.js +69 -65
  53. package/dist-ui-lib/index.js.map +1 -1
  54. package/package.json +27 -25
  55. package/src/core/control-panel.ts +2 -1
  56. package/src/core/gateway.ts +28 -29
  57. package/src/plugins/auth/adapters/supertokens-adapter.ts +54 -13
  58. package/src/plugins/auth/auth-plugin.ts +6 -5
  59. package/src/plugins/auth/env-config.ts +4 -0
  60. package/src/plugins/auth/types.ts +11 -0
  61. package/src/plugins/maintenance/seed-executor.ts +5 -4
  62. package/src/plugins/maintenance-plugin.ts +28 -4
  63. package/src/plugins/postgres-plugin.test.ts +78 -0
  64. package/src/plugins/postgres-plugin.ts +39 -11
  65. package/src/plugins/rate-limit/env-config.ts +4 -4
  66. package/src/utils/index.ts +1 -0
  67. package/src/utils/url.test.ts +43 -0
  68. package/src/utils/url.ts +21 -0
  69. package/ui/src/dashboard/widgets/AuthStatusWidget.tsx +3 -8
  70. package/ui/src/dashboard/widgets/DatabaseOperationsWidget.tsx +17 -8
  71. package/dist-ui/assets/index-Cez_jyhl.js +0 -532
@@ -0,0 +1,43 @@
1
+ import { sanitizeUrl } from './url.js';
2
+
3
+ describe('sanitizeUrl', () => {
4
+ it('allows https URLs', () => {
5
+ expect(sanitizeUrl('https://example.com')).toBe('https://example.com');
6
+ });
7
+
8
+ it('allows http URLs', () => {
9
+ expect(sanitizeUrl('http://example.com/path')).toBe('http://example.com/path');
10
+ });
11
+
12
+ it('allows relative URLs starting with /', () => {
13
+ expect(sanitizeUrl('/relative/path')).toBe('/relative/path');
14
+ });
15
+
16
+ it('blocks javascript: protocol', () => {
17
+ expect(sanitizeUrl('javascript:alert(document.cookie)')).toBe('#');
18
+ });
19
+
20
+ it('blocks javascript: with uppercase', () => {
21
+ expect(sanitizeUrl('JavaScript:alert(1)')).toBe('#');
22
+ });
23
+
24
+ it('blocks data: protocol', () => {
25
+ expect(sanitizeUrl('data:text/html,<h1>test</h1>')).toBe('#');
26
+ });
27
+
28
+ it('blocks vbscript: protocol', () => {
29
+ expect(sanitizeUrl('vbscript:msgbox(1)')).toBe('#');
30
+ });
31
+
32
+ it('returns fallback for empty string', () => {
33
+ expect(sanitizeUrl('')).toBe('#');
34
+ });
35
+
36
+ it('returns custom fallback when provided', () => {
37
+ expect(sanitizeUrl('javascript:alert(1)', '/safe')).toBe('/safe');
38
+ });
39
+
40
+ it('returns fallback for malformed URLs', () => {
41
+ expect(sanitizeUrl('not a url at all')).toBe('#');
42
+ });
43
+ });
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Sanitizes a URL to prevent javascript: and other dangerous protocol injections
3
+ * when interpolating user-supplied URLs into HTML href attributes.
4
+ *
5
+ * Allows: http:, https:, and relative URLs (starting with /).
6
+ * Returns fallback for any other protocol (e.g., javascript:, data:, vbscript:).
7
+ */
8
+ export function sanitizeUrl(url: string, fallback = '#'): string {
9
+ if (!url) return fallback;
10
+ // Allow relative URLs
11
+ if (url.startsWith('/')) return url;
12
+ try {
13
+ const parsed = new URL(url);
14
+ if (parsed.protocol === 'http:' || parsed.protocol === 'https:') {
15
+ return url;
16
+ }
17
+ return fallback;
18
+ } catch {
19
+ return fallback;
20
+ }
21
+ }
@@ -12,14 +12,9 @@ import { Box, Typography, Chip, CircularProgress, Alert } from '@mui/material';
12
12
  import CheckCircleIcon from '@mui/icons-material/CheckCircle';
13
13
  import ErrorIcon from '@mui/icons-material/Error';
14
14
  import BlockIcon from '@mui/icons-material/Block';
15
- import { api } from '../../api/controlPanelApi';
15
+ import { api, type AuthConfigStatus } from '../../api/controlPanelApi';
16
16
 
17
- interface AuthStatus {
18
- state: 'enabled' | 'disabled' | 'error';
19
- adapter: string | null;
20
- error?: string;
21
- missingVars?: string[];
22
- }
17
+ type AuthStatus = AuthConfigStatus;
23
18
 
24
19
  const adapterLabels: Record<string, string> = {
25
20
  supertokens: 'SuperTokens',
@@ -36,7 +31,7 @@ export function AuthStatusWidget() {
36
31
  useEffect(() => {
37
32
  const fetchStatus = async () => {
38
33
  try {
39
- const data = await api.fetch<AuthStatus>('/auth/config/status');
34
+ const data = await api.getAuthConfigStatus();
40
35
  setStatus(data);
41
36
  } catch (err) {
42
37
  setError(err instanceof Error ? err.message : 'Failed to fetch auth status');
@@ -33,6 +33,7 @@ interface DatabaseStatus {
33
33
  user?: string;
34
34
  host?: string;
35
35
  port?: number;
36
+ managed?: boolean;
36
37
  errorMessage?: string;
37
38
  autoInitializeEnabled: boolean;
38
39
  adminCredentialsProvided: boolean;
@@ -360,6 +361,12 @@ export const DatabaseOperationsWidget: React.FC<DatabaseOperationsWidgetProps> =
360
361
  </Typography>
361
362
  </Box>
362
363
 
364
+ {status.managed && (
365
+ <Alert severity="info" sx={{ mt: 2 }}>
366
+ Managed database (Neon / Supabase). Delete and recreate is disabled — manage your database through the provider dashboard.
367
+ </Alert>
368
+ )}
369
+
363
370
  {!status.connected && !operating && (
364
371
  <Box sx={{ display: 'flex', gap: 1, mt: 2 }}>
365
372
  <Button
@@ -370,14 +377,16 @@ export const DatabaseOperationsWidget: React.FC<DatabaseOperationsWidgetProps> =
370
377
  >
371
378
  Initialize Database
372
379
  </Button>
373
- <Button
374
- variant="contained"
375
- color="error"
376
- onClick={() => startOperation('recreate')}
377
- size="small"
378
- >
379
- Recreate Database
380
- </Button>
380
+ {!status.managed && (
381
+ <Button
382
+ variant="contained"
383
+ color="error"
384
+ onClick={() => startOperation('recreate')}
385
+ size="small"
386
+ >
387
+ Recreate Database
388
+ </Button>
389
+ )}
381
390
  </Box>
382
391
  )}
383
392
  </CardContent>