postbase 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 (126) hide show
  1. package/.github/workflows/test.yml +74 -0
  2. package/CLA.md +60 -0
  3. package/CONTRIBUTORS.md +35 -0
  4. package/LICENSE +661 -0
  5. package/README.md +211 -0
  6. package/admin/404.html +33 -0
  7. package/admin/README.md +21 -0
  8. package/admin/index.html +15 -0
  9. package/admin/jsconfig.json +20 -0
  10. package/admin/lib/postbase.js +222 -0
  11. package/admin/package-lock.json +3746 -0
  12. package/admin/package.json +27 -0
  13. package/admin/public/assets/img/admin-ui.png +0 -0
  14. package/admin/public/assets/img/blank-profile-picture-960_720.webp +0 -0
  15. package/admin/public/assets/img/chart-active-users.png +0 -0
  16. package/admin/public/assets/img/icon-transparent.png +0 -0
  17. package/admin/src/App.jsx +48 -0
  18. package/admin/src/auth.js +11 -0
  19. package/admin/src/common/formatDateTime.js +18 -0
  20. package/admin/src/components/AuthPanel.jsx +88 -0
  21. package/admin/src/components/Header.jsx +67 -0
  22. package/admin/src/main.jsx +6 -0
  23. package/admin/src/pages/Dashboard.jsx +24 -0
  24. package/admin/src/pages/Home.jsx +52 -0
  25. package/admin/src/pages/Login.jsx +10 -0
  26. package/admin/src/pages/authentication/Users.jsx +199 -0
  27. package/admin/src/pages/firestore/Database.jsx +29 -0
  28. package/admin/src/pages/storage/files.jsx +29 -0
  29. package/admin/src/postbase.js +15 -0
  30. package/admin/src/styles.css +3 -0
  31. package/admin/tailwind.config.cjs +11 -0
  32. package/admin/template.env +2 -0
  33. package/admin/vite.config.js +21 -0
  34. package/assets/img/HomePageScreenshot.png +0 -0
  35. package/assets/img/better-auth-logo-dark.136b122f.png +0 -0
  36. package/assets/img/better-auth-logo-light.4b03f444.png +0 -0
  37. package/assets/img/expresjs.png +0 -0
  38. package/assets/img/icon-transparent.png +0 -0
  39. package/assets/img/icon.png +0 -0
  40. package/assets/img/letsencrypt-logo-horizontal.png +0 -0
  41. package/assets/img/logo.png +0 -0
  42. package/assets/img/node.js_logo.png +0 -0
  43. package/assets/img/nodejsLight.svg +39 -0
  44. package/assets/img/postgres.png +0 -0
  45. package/backend/README.md +49 -0
  46. package/backend/admin/auth.js +9 -0
  47. package/backend/app.js +68 -0
  48. package/backend/auth.js +92 -0
  49. package/backend/env.js +12 -0
  50. package/backend/lib/postbase/adminClient.js +520 -0
  51. package/backend/lib/postbase/compat/admin.js +44 -0
  52. package/backend/lib/postbase/db.js +17 -0
  53. package/backend/lib/postbase/genericRouter.js +603 -0
  54. package/backend/lib/postbase/local-storage.js +56 -0
  55. package/backend/lib/postbase/metadataCache.js +32 -0
  56. package/backend/lib/postbase/middlewares/auth.js +57 -0
  57. package/backend/lib/postbase/migrations/1765239687559_rtdb-nodes.js +93 -0
  58. package/backend/lib/postbase/package-lock.json +5873 -0
  59. package/backend/lib/postbase/package.json +19 -0
  60. package/backend/lib/postbase/rtdb/router.js +190 -0
  61. package/backend/lib/postbase/rtdb/rulesEngine.js +63 -0
  62. package/backend/lib/postbase/rtdb/ws.js +84 -0
  63. package/backend/lib/postbase/rulesEngine.js +62 -0
  64. package/backend/lib/postbase/storage.js +130 -0
  65. package/backend/lib/postbase/tests/README.md +22 -0
  66. package/backend/lib/postbase/tests/db.js +9 -0
  67. package/backend/lib/postbase/tests/rtdb.rest.test.js +46 -0
  68. package/backend/lib/postbase/tests/rtdb.ws.test.js +113 -0
  69. package/backend/lib/postbase/tests/rules.js +26 -0
  70. package/backend/lib/postbase/tests/testServer.js +46 -0
  71. package/backend/lib/postbase/websocket.js +131 -0
  72. package/backend/local.js +6 -0
  73. package/backend/main.js +20 -0
  74. package/backend/middlewares/auth_middleware.js +10 -0
  75. package/backend/migrations/1762137399366-init.sql +98 -0
  76. package/backend/migrations/1762137399367_init_jsonb_schema.js +68 -0
  77. package/backend/migrations/1762149999999_enable_realtime_changes.js +48 -0
  78. package/backend/migrations/1765224247654_rtdb-nodes.js +93 -0
  79. package/backend/package-lock.json +2374 -0
  80. package/backend/package.json +27 -0
  81. package/backend/postbase_db_rules.js +128 -0
  82. package/backend/postbase_rtdb_rules.js +27 -0
  83. package/backend/postbase_storage_rules.js +45 -0
  84. package/backend/template.env +10 -0
  85. package/backend-systemd/README.md +39 -0
  86. package/backend-systemd/your_website.com.service +12 -0
  87. package/frontend/404.html +33 -0
  88. package/frontend/README.md +25 -0
  89. package/frontend/index.html +15 -0
  90. package/frontend/jsconfig.json +20 -0
  91. package/frontend/lib/postbase/auth.js +132 -0
  92. package/frontend/lib/postbase/compat/firebase/app.js +3 -0
  93. package/frontend/lib/postbase/compat/firebase/auth.js +115 -0
  94. package/frontend/lib/postbase/compat/firebase/database.js +11 -0
  95. package/frontend/lib/postbase/compat/firebase/firestore/lite.js +61 -0
  96. package/frontend/lib/postbase/compat/firebase/storage.js +10 -0
  97. package/frontend/lib/postbase/db.js +657 -0
  98. package/frontend/lib/postbase/package-lock.json +6284 -0
  99. package/frontend/lib/postbase/package.json +17 -0
  100. package/frontend/lib/postbase/rtdb.js +108 -0
  101. package/frontend/lib/postbase/storage.js +293 -0
  102. package/frontend/lib/postbase/tests/rtdb.client.test.js +88 -0
  103. package/frontend/lib/postbase/tests/waitFor.js +13 -0
  104. package/frontend/lib/postbase/utils.js +1 -0
  105. package/frontend/package-lock.json +2977 -0
  106. package/frontend/package.json +24 -0
  107. package/frontend/src/App.jsx +38 -0
  108. package/frontend/src/auth.js +52 -0
  109. package/frontend/src/components/AuthPanel.jsx +85 -0
  110. package/frontend/src/components/Header.jsx +54 -0
  111. package/frontend/src/main.jsx +5 -0
  112. package/frontend/src/pages/Dashboard.jsx +24 -0
  113. package/frontend/src/pages/Home.jsx +178 -0
  114. package/frontend/src/pages/Login.jsx +10 -0
  115. package/frontend/src/postbase.js +14 -0
  116. package/frontend/src/styles.css +1 -0
  117. package/frontend/tailwind.config.cjs +11 -0
  118. package/frontend/template.env +2 -0
  119. package/frontend/vite.config.js +18 -0
  120. package/git/hooks/README.md +31 -0
  121. package/git/hooks/post-receive +26 -0
  122. package/nginx/README.md +84 -0
  123. package/nginx/apt/www.your_website.com.conf +80 -0
  124. package/nginx/homebrew/www.your_website.com.conf +80 -0
  125. package/nginx/letsencrypt/README +14 -0
  126. package/package.json +8 -0
@@ -0,0 +1,57 @@
1
+ // server/middleware/auth.js
2
+ import { runQuery } from '../db.js';
3
+
4
+ export function authMiddleware(pool) {
5
+ return async function sessionAuth(req, res, next) {
6
+ try {
7
+ const header = req.get('authorization') || '';
8
+ if (!header.startsWith('Bearer ')) {
9
+ req.auth = null;
10
+ return next();
11
+ }
12
+ const token = header.slice(7).trim();
13
+
14
+ // Lookup session in database
15
+ const sql = `
16
+ SELECT s.*, u.id AS user_id, u.email, u.name, u.role
17
+ FROM "session" s
18
+ JOIN "user" u ON u.id = s."userId"
19
+ WHERE s.token = $1
20
+ LIMIT 1
21
+ `;
22
+ const result = await runQuery(pool, sql, [token]);
23
+ if (!result.rowCount) {
24
+ req.auth = null;
25
+ return next();
26
+ }
27
+
28
+ const session = result.rows[0];
29
+ const now = new Date();
30
+ if (new Date(session.expires_at) < now) {
31
+ req.auth = null; // expired
32
+ return next();
33
+ }
34
+
35
+ // Attach verified auth info
36
+ req.auth = {
37
+ id: String(session.user_id),
38
+ session_id: session.id,
39
+ expires_at: session.expires_at,
40
+ token,
41
+ };
42
+
43
+ req.user = {
44
+ id: String(session.user_id),
45
+ email: session.email,
46
+ name: session.name,
47
+ role: session.role,
48
+ };
49
+
50
+ next();
51
+ } catch (err) {
52
+ console.error('auth middleware error', err);
53
+ req.auth = null;
54
+ next();
55
+ }
56
+ };
57
+ }
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @type {import('node-pg-migrate').ColumnDefinitions | undefined}
3
+ */
4
+ export const shorthands = undefined;
5
+
6
+ /**
7
+ * @param pgm {import('node-pg-migrate').MigrationBuilder}
8
+ * @param run {() => void | undefined}
9
+ * @returns {Promise<void> | void}
10
+ */
11
+ export const up = (pgm) => {
12
+ // ---- Extensions ----
13
+ pgm.createExtension('ltree', { ifNotExists: true });
14
+
15
+ // ---- Table ----
16
+ pgm.createTable('rtdb_nodes', {
17
+ path: {
18
+ type: 'text',
19
+ primaryKey: true,
20
+ notNull: true,
21
+ },
22
+
23
+ parent_path: {
24
+ type: 'text',
25
+ notNull: false,
26
+ },
27
+
28
+ key: {
29
+ type: 'text',
30
+ notNull: true,
31
+ },
32
+
33
+ value: {
34
+ type: 'jsonb',
35
+ notNull: true,
36
+ },
37
+
38
+ version: {
39
+ type: 'bigint',
40
+ notNull: true,
41
+ default: 1,
42
+ },
43
+
44
+ updated_at: {
45
+ type: 'timestamptz',
46
+ notNull: true,
47
+ default: pgm.func('now()'),
48
+ },
49
+
50
+ // Generated ltree column for fast subtree queries
51
+ path_ltree: {
52
+ type: 'ltree',
53
+ generated: {
54
+ as: "replace(path, '/', '.')::ltree",
55
+ stored: true,
56
+ },
57
+ },
58
+ });
59
+
60
+ // ---- Indexes ----
61
+
62
+ // Fast exact + prefix lookups (LIKE 'a/b/%')
63
+ pgm.createIndex('rtdb_nodes', 'parent_path', {
64
+ name: 'rtdb_nodes_parent_idx',
65
+ });
66
+
67
+ pgm.createIndex('rtdb_nodes', 'value', {
68
+ name: 'rtdb_nodes_value_gin_idx',
69
+ method: 'gin',
70
+ });
71
+
72
+ pgm.createIndex('rtdb_nodes', 'path_ltree', {
73
+ name: 'rtdb_nodes_ltree_idx',
74
+ method: 'gist',
75
+ });
76
+
77
+ // ✅ PREFIX INDEX (RAW SQL – avoids TS error)
78
+ pgm.sql(`
79
+ CREATE INDEX rtdb_nodes_path_prefix_idx
80
+ ON rtdb_nodes (path text_pattern_ops)
81
+ `);
82
+ };
83
+
84
+ /**
85
+ * @param pgm {import('node-pg-migrate').MigrationBuilder}
86
+ * @param run {() => void | undefined}
87
+ * @returns {Promise<void> | void}
88
+ */
89
+ export const down = (pgm) => {
90
+ pgm.sql(`DROP INDEX IF EXISTS rtdb_nodes_path_prefix_idx`);
91
+ pgm.dropTable('rtdb_nodes', { ifExists: true });
92
+ pgm.dropExtension('ltree', { ifExists: true });
93
+ };