sitepaige-mcp-server 1.0.2 → 1.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 (47) hide show
  1. package/components/IntegrationComponent.tsx +1 -0
  2. package/components/admin.tsx +30 -27
  3. package/components/auth.tsx +9 -9
  4. package/components/cta.tsx +3 -10
  5. package/components/headerlogin.tsx +9 -9
  6. package/components/login.tsx +90 -11
  7. package/components/logincallback.tsx +1 -0
  8. package/components/menu.tsx +0 -6
  9. package/components/profile.tsx +12 -11
  10. package/defaultapp/api/Auth/resend-verification/route.ts +130 -0
  11. package/defaultapp/api/Auth/route.ts +39 -49
  12. package/defaultapp/api/Auth/signup/route.ts +5 -15
  13. package/defaultapp/api/Auth/verify-email/route.ts +12 -5
  14. package/defaultapp/api/admin/users/route.ts +5 -3
  15. package/defaultapp/auth/auth.ts +9 -9
  16. package/defaultapp/db-mysql.ts +1 -1
  17. package/defaultapp/db-password-auth.ts +37 -0
  18. package/defaultapp/db-postgres.ts +1 -1
  19. package/defaultapp/db-sqlite.ts +1 -1
  20. package/defaultapp/db-users.ts +73 -73
  21. package/defaultapp/middleware.ts +15 -17
  22. package/dist/components/IntegrationComponent.tsx +1 -0
  23. package/dist/components/admin.tsx +30 -27
  24. package/dist/components/auth.tsx +9 -9
  25. package/dist/components/cta.tsx +3 -10
  26. package/dist/components/headerlogin.tsx +9 -9
  27. package/dist/components/login.tsx +90 -11
  28. package/dist/components/logincallback.tsx +1 -0
  29. package/dist/components/menu.tsx +0 -6
  30. package/dist/components/profile.tsx +12 -11
  31. package/dist/defaultapp/api/Auth/resend-verification/route.ts +130 -0
  32. package/dist/defaultapp/api/Auth/route.ts +39 -49
  33. package/dist/defaultapp/api/Auth/signup/route.ts +5 -15
  34. package/dist/defaultapp/api/Auth/verify-email/route.ts +12 -5
  35. package/dist/defaultapp/api/admin/users/route.ts +5 -3
  36. package/dist/defaultapp/auth/auth.ts +9 -9
  37. package/dist/defaultapp/db-mysql.ts +1 -1
  38. package/dist/defaultapp/db-password-auth.ts +37 -0
  39. package/dist/defaultapp/db-postgres.ts +1 -1
  40. package/dist/defaultapp/db-sqlite.ts +1 -1
  41. package/dist/defaultapp/db-users.ts +73 -73
  42. package/dist/defaultapp/middleware.ts +15 -17
  43. package/dist/generators/sql.js +11 -3
  44. package/dist/generators/sql.js.map +1 -1
  45. package/dist/generators/views.js +14 -14
  46. package/dist/generators/views.js.map +1 -1
  47. package/package.json +1 -1
@@ -35,25 +35,32 @@ export async function GET(request: Request) {
35
35
  // Create or update user in the main Users table
36
36
  const user = await upsertUser(
37
37
  `password_${authRecord.id}`, // Unique OAuth ID for password users
38
- 'username' as any, // Source type
38
+ 'userpass' as any, // Source type
39
39
  authRecord.email.split('@')[0], // Username from email
40
40
  authRecord.email,
41
41
  undefined // No avatar for password auth
42
42
  );
43
43
 
44
+ if (!user) {
45
+ return NextResponse.json(
46
+ { error: 'Failed to create user account' },
47
+ { status: 500 }
48
+ );
49
+ }
50
+
44
51
  // Auto-login the user after verification
45
52
  const db = await db_init();
46
53
 
47
54
  // Delete existing sessions for this user
48
55
  const existingSessions = await db_query(db,
49
- "SELECT ID FROM usersession WHERE userid = ?",
56
+ "SELECT id FROM usersession WHERE userid = ?",
50
57
  [user.userid]
51
58
  );
52
59
 
53
60
  if (existingSessions && existingSessions.length > 0) {
54
- const sessionIds = existingSessions.map(session => session.ID);
61
+ const sessionIds = existingSessions.map(session => session.id);
55
62
  const placeholders = sessionIds.map(() => '?').join(',');
56
- await db_query(db, `DELETE FROM usersession WHERE ID IN (${placeholders})`, sessionIds);
63
+ await db_query(db, `DELETE FROM usersession WHERE id IN (${placeholders})`, sessionIds);
57
64
  }
58
65
 
59
66
  // Generate secure session token and ID
@@ -62,7 +69,7 @@ export async function GET(request: Request) {
62
69
 
63
70
  // Create new session with secure token
64
71
  await db_query(db,
65
- "INSERT INTO usersession (ID, SessionToken, userid, ExpirationDate) VALUES (?, ?, ?, ?)",
72
+ "INSERT INTO usersession (id, sessiontoken, userid, expirationdate) VALUES (?, ?, ?, ?)",
66
73
  [sessionId, sessionToken, user.userid, new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString()]
67
74
  );
68
75
 
@@ -28,9 +28,11 @@ async function checkAdminAuth(): Promise<{ isAdmin: boolean; userId?: string }>
28
28
 
29
29
  // Get session
30
30
  const sessions = await db_query(db,
31
- "SELECT userid FROM UserSession WHERE SessionToken = ?",
31
+ "SELECT userid FROM usersession WHERE sessiontoken = ?",
32
32
  [sessionId]
33
33
  );
34
+
35
+ console.log(sessions);
34
36
 
35
37
  if (sessions.length === 0) {
36
38
  return { isAdmin: false };
@@ -38,8 +40,8 @@ async function checkAdminAuth(): Promise<{ isAdmin: boolean; userId?: string }>
38
40
 
39
41
  // Check if user is admin
40
42
  const user = await getUserByID(sessions[0].userid);
41
-
42
- if (!user || user.UserLevel !== 2) {
43
+
44
+ if (!user || user.userlevel !== 2) {
43
45
  return { isAdmin: false };
44
46
  }
45
47
 
@@ -1,14 +1,14 @@
1
1
  import { cookies } from 'next/headers';
2
2
 
3
- export async function check_auth(db: any, db_query: any): Promise<{ userid: string, UserLevel: number, UserTier: number, IsAdmin: boolean }> {
3
+ export async function check_auth(db: any, db_query: any): Promise<{ userid: string, userlevel: number, usertier: number, isadmin: boolean }> {
4
4
  const cookieStore = await cookies();
5
5
  const sessionId = cookieStore.get('session_id')?.value;
6
6
 
7
7
  const sessionInfo = {
8
8
  userid: '',
9
- UserLevel: 0,
10
- UserTier: 0,
11
- IsAdmin: false
9
+ userlevel: 0,
10
+ usertier: 0,
11
+ isadmin: false
12
12
  };
13
13
 
14
14
  if (!sessionId) {
@@ -16,16 +16,16 @@ export async function check_auth(db: any, db_query: any): Promise<{ userid: stri
16
16
  }
17
17
 
18
18
  // SQLite is case-insensitive for identifiers, but use standard column names (no quotes, correct names)
19
- const session = await db_query(db, 'SELECT userid FROM UserSession WHERE SessionToken = ?', [sessionId]);
19
+ const session = await db_query(db, 'SELECT userid FROM usersession WHERE sessiontoken = ?', [sessionId]);
20
20
  if (session.length > 0) {
21
21
  sessionInfo.userid = session[0].userid;
22
22
 
23
23
  // In your Users table, the primary key is userid, and there is no IsAdmin column, but UserLevel (2 = admin)
24
- const user = await db_query(db, 'SELECT UserLevel, UserTier FROM Users WHERE userid = ?', [session[0].userid]);
24
+ const user = await db_query(db, 'SELECT userlevel, usertier FROM users WHERE userid = ?', [session[0].userid]);
25
25
  if (user.length > 0) {
26
- sessionInfo.UserLevel = user[0].UserLevel;
27
- sessionInfo.IsAdmin = user[0].UserLevel === 2;
28
- sessionInfo.UserTier = user[0].UserTier;
26
+ sessionInfo.userlevel = user[0].userlevel;
27
+ sessionInfo.isadmin = user[0].userlevel === 2;
28
+ sessionInfo.usertier = user[0].usertier;
29
29
  }
30
30
  }
31
31
  return sessionInfo;
@@ -95,7 +95,7 @@ export async function db_query(
95
95
  */
96
96
  export function db_migrate(model: Model, dbType: string): string {
97
97
 
98
- const sanitizedTableName = model.name;
98
+ const sanitizedTableName = model.name.toLowerCase().replace(/\s+/g, '_');
99
99
 
100
100
  // Start with the model's fields
101
101
  let fields = [...model.fields];
@@ -295,6 +295,43 @@ export async function updatePassword(email: string, currentPassword: string, new
295
295
  return true;
296
296
  }
297
297
 
298
+ /**
299
+ * Regenerate email verification token for unverified accounts
300
+ */
301
+ export async function regenerateVerificationToken(email: string): Promise<{ passwordAuth: PasswordAuth; verificationToken: string } | null> {
302
+ const client = await db_init();
303
+
304
+ const authRecord = await getPasswordAuthByEmail(email);
305
+ if (!authRecord) {
306
+ return null;
307
+ }
308
+
309
+ // Only regenerate for unverified accounts
310
+ if (authRecord.emailverified) {
311
+ throw new Error('Email is already verified');
312
+ }
313
+
314
+ // Generate new verification token
315
+ const verificationToken = randomBytes(32).toString('base64url');
316
+ const verificationTokenExpires = new Date(Date.now() + 24 * 60 * 60 * 1000); // 24 hours
317
+
318
+ await db_query(client,
319
+ `UPDATE passwordauth
320
+ SET verificationtoken = ?,
321
+ verificationtokenexpires = ?,
322
+ updatedat = CURRENT_TIMESTAMP
323
+ WHERE id = ?`,
324
+ [verificationToken, verificationTokenExpires.toISOString(), authRecord.id]
325
+ );
326
+
327
+ const updatedAuth = await getPasswordAuthByEmail(email);
328
+ if (!updatedAuth) {
329
+ throw new Error('Failed to update verification token');
330
+ }
331
+
332
+ return { passwordAuth: updatedAuth, verificationToken };
333
+ }
334
+
298
335
  /**
299
336
  * Check if an email is already registered
300
337
  */
@@ -101,7 +101,7 @@ export async function db_query(
101
101
  */
102
102
  export function db_migrate(model: Model, dbType: string): string {
103
103
 
104
- const sanitizedTableName = model.name;
104
+ const sanitizedTableName = model.name.toLowerCase().replace(/\s+/g, '_');
105
105
 
106
106
  // Start with the model's fields
107
107
  let fields = [...model.fields];
@@ -175,7 +175,7 @@ export async function db_query(
175
175
  export function db_migrate(model: Model, dbType: string): string {
176
176
  // Special handling for auth tables - create them first
177
177
 
178
- const sanitizedTableName = model.name;
178
+ const sanitizedTableName = model.name.toLowerCase().replace(/\s+/g, '_');
179
179
 
180
180
  // Start with the model's fields
181
181
  let fields = [...model.fields];
@@ -9,33 +9,33 @@ import * as crypto from 'node:crypto';
9
9
 
10
10
  export interface User {
11
11
  userid: string;
12
- OAuthID: string;
13
- Source: 'google' | 'facebook' | 'apple' | 'github';
14
- UserName: string;
15
- Email?: string;
16
- AvatarURL?: string;
17
- UserLevel: number; // 0: everyone, 1: registered user, 2: admin
18
- LastLoginDate: string;
19
- CreatedDate: string;
20
- IsActive: boolean;
12
+ oauthid: string;
13
+ source: 'google' | 'facebook' | 'apple' | 'github' | 'userpass';
14
+ username: string;
15
+ email?: string;
16
+ avatarurl?: string;
17
+ userlevel: number; // 0: everyone, 1: registered user, 2: admin
18
+ lastlogindate: string;
19
+ createddate: string;
20
+ isactive: boolean;
21
21
  }
22
22
 
23
23
  export interface UserSession {
24
- ID: string;
25
- SessionToken: string;
24
+ id: string;
25
+ sessiontoken: string;
26
26
  userid: string;
27
- ExpirationDate: string;
27
+ expirationdate: string;
28
28
  }
29
29
 
30
30
  export interface OAuthToken {
31
- ID: string;
31
+ id: string;
32
32
  userid: string;
33
- Provider: 'google' | 'facebook' | 'apple' | 'github';
34
- AccessToken: string;
35
- RefreshToken?: string;
36
- ExpiresAt?: string;
37
- CreatedAt: string;
38
- UpdatedAt: string;
33
+ provider: 'google' | 'facebook' | 'apple' | 'github';
34
+ accesstoken: string;
35
+ refreshtoken?: string;
36
+ expiresat?: string;
37
+ createdat: string;
38
+ updatedat: string;
39
39
  }
40
40
 
41
41
  /**
@@ -46,9 +46,9 @@ export async function getAllUsers(): Promise<User[]> {
46
46
 
47
47
  const users = await db_query(client,
48
48
  `SELECT * FROM users
49
- WHERE IsActive = ?
50
- ORDER BY UserLevel DESC, UserName ASC`,
51
- [true]
49
+ WHERE isactive = ?
50
+ ORDER BY userlevel DESC, username ASC`,
51
+ [1] // Use 1 instead of true for PostgreSQL compatibility
52
52
  );
53
53
 
54
54
  return users as User[];
@@ -61,8 +61,8 @@ export async function getUserByOAuthID(oauthId: string): Promise<User | null> {
61
61
  const client = await db_init();
62
62
 
63
63
  const users = await db_query(client,
64
- "SELECT * FROM users WHERE OAuthID = ? AND IsActive = ?",
65
- [oauthId, true]
64
+ "SELECT * FROM users WHERE oauthid = ? AND isactive = ?",
65
+ [oauthId, 1] // Use 1 instead of true for PostgreSQL compatibility
66
66
  );
67
67
 
68
68
  return users.length > 0 ? users[0] as User : null;
@@ -75,8 +75,8 @@ export async function getUserByID(userId: string): Promise<User | null> {
75
75
  const client = await db_init();
76
76
 
77
77
  const users = await db_query(client,
78
- "SELECT * FROM users WHERE userid = ? AND IsActive = ?",
79
- [userId, true]
78
+ "SELECT * FROM users WHERE userid = ? AND isactive = ?",
79
+ [userId, 1] // Use 1 instead of true for PostgreSQL compatibility
80
80
  );
81
81
 
82
82
  return users.length > 0 ? users[0] as User : null;
@@ -87,7 +87,7 @@ export async function getUserByID(userId: string): Promise<User | null> {
87
87
  */
88
88
  export async function upsertUser(
89
89
  oauthId: string,
90
- source: 'google' | 'facebook' | 'apple' | 'github',
90
+ source: 'google' | 'facebook' | 'apple' | 'github' | 'userpass',
91
91
  userName: string,
92
92
  email?: string,
93
93
  avatarUrl?: string
@@ -101,9 +101,9 @@ export async function upsertUser(
101
101
  // Update existing user
102
102
  await db_query(client,
103
103
  `UPDATE users
104
- SET UserName = ?, Email = COALESCE(?, Email), AvatarURL = ?,
105
- LastLoginDate = CURRENT_TIMESTAMP, Source = ?
106
- WHERE OAuthID = ?`,
104
+ SET username = ?, email = COALESCE(?, email), avatarurl = ?,
105
+ lastlogindate = CURRENT_TIMESTAMP, source = ?
106
+ WHERE oauthid = ?`,
107
107
  [userName, email, avatarUrl || '', source, oauthId]
108
108
  );
109
109
 
@@ -119,10 +119,10 @@ export async function upsertUser(
119
119
 
120
120
  await db_query(client,
121
121
  `INSERT INTO users
122
- (userid, OAuthID, Source, UserName, Email, AvatarURL, UserLevel, UserTier,
123
- LastLoginDate, CreatedDate, IsActive)
122
+ (userid, oauthid, source, username, email, avatarurl, userlevel, usertier,
123
+ lastlogindate, createddate, isactive)
124
124
  VALUES (?, ?, ?, ?, ?, ?, ?, 0, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, ?)`,
125
- [userId, oauthId, source, userName, email || null, avatarUrl || '', permissionLevel, true]
125
+ [userId, oauthId, source, userName, email || null, avatarUrl || '', permissionLevel, 1] // Use 1 instead of true for PostgreSQL compatibility
126
126
  );
127
127
 
128
128
  return (await getUserByOAuthID(oauthId))!;
@@ -141,8 +141,8 @@ export async function updateUserPermission(
141
141
  // Ensure there's always at least one admin
142
142
  if (permissionLevel < 2) {
143
143
  const admins = await db_query(client,
144
- "SELECT COUNT(*) as count FROM users WHERE UserLevel = ? AND userid != ? AND IsActive = ?",
145
- [2, userId, true]
144
+ "SELECT COUNT(*) as count FROM users WHERE userlevel = ? AND userid != ? AND isactive = ?",
145
+ [2, userId, 1] // Use 1 instead of true for PostgreSQL compatibility
146
146
  );
147
147
 
148
148
  if (admins[0].count === 0) {
@@ -151,7 +151,7 @@ export async function updateUserPermission(
151
151
  }
152
152
 
153
153
  const result = await db_query(client,
154
- "UPDATE users SET UserLevel = ? WHERE userid = ?",
154
+ "UPDATE users SET userlevel = ? WHERE userid = ?",
155
155
  [permissionLevel, userId]
156
156
  );
157
157
 
@@ -166,10 +166,10 @@ export async function deleteUser(userId: string): Promise<boolean> {
166
166
 
167
167
  // Ensure there's always at least one admin
168
168
  const user = await getUserByID(userId);
169
- if (user && user.UserLevel === 2) {
169
+ if (user && user.userlevel === 2) {
170
170
  const admins = await db_query(client,
171
- "SELECT COUNT(*) as count FROM users WHERE UserLevel = ? AND userid != ? AND IsActive = ?",
172
- [2, userId, true]
171
+ "SELECT COUNT(*) as count FROM users WHERE userlevel = ? AND userid != ? AND isactive = ?",
172
+ [2, userId, 1] // Use 1 instead of true for PostgreSQL compatibility
173
173
  );
174
174
 
175
175
  if (admins[0].count === 0) {
@@ -179,8 +179,8 @@ export async function deleteUser(userId: string): Promise<boolean> {
179
179
 
180
180
  // Soft delete the user
181
181
  const result = await db_query(client,
182
- "UPDATE users SET IsActive = ? WHERE userid = ?",
183
- [false, userId]
182
+ "UPDATE users SET isactive = ? WHERE userid = ?",
183
+ [0, userId] // Use 0 instead of false for PostgreSQL compatibility
184
184
  );
185
185
 
186
186
  return result[0].changes > 0;
@@ -200,12 +200,12 @@ export async function getUserStats(): Promise<{
200
200
  const stats = await db_query(client, `
201
201
  SELECT
202
202
  COUNT(*) as totalUsers,
203
- SUM(CASE WHEN UserLevel = 2 THEN 1 ELSE 0 END) as admins,
204
- SUM(CASE WHEN UserLevel = 1 THEN 1 ELSE 0 END) as registeredUsers,
205
- SUM(CASE WHEN UserLevel = 0 THEN 1 ELSE 0 END) as guestUsers
203
+ SUM(CASE WHEN userlevel = 2 THEN 1 ELSE 0 END) as admins,
204
+ SUM(CASE WHEN userlevel = 1 THEN 1 ELSE 0 END) as registeredUsers,
205
+ SUM(CASE WHEN userlevel = 0 THEN 1 ELSE 0 END) as guestUsers
206
206
  FROM users
207
- WHERE IsActive = ?
208
- `, [true]);
207
+ WHERE isactive = ?
208
+ `, [1]); // Use 1 instead of true for PostgreSQL compatibility
209
209
 
210
210
  return stats[0];
211
211
  }
@@ -217,7 +217,7 @@ export async function cleanupExpiredSessions(): Promise<number> {
217
217
  const client = await db_init();
218
218
 
219
219
  const result = await db_query(client,
220
- "DELETE FROM usersession WHERE ExpirationDate < CURRENT_TIMESTAMP"
220
+ "DELETE FROM usersession WHERE expirationdate::TIMESTAMP < CURRENT_TIMESTAMP"
221
221
  );
222
222
 
223
223
  return result[0].changes;
@@ -241,14 +241,14 @@ export async function storeOAuthToken(
241
241
 
242
242
  // Delete existing tokens for this user/provider combo
243
243
  await db_query(client,
244
- "DELETE FROM oauthtokens WHERE userid = ? AND Provider = ?",
244
+ "DELETE FROM oauthtokens WHERE userid = ? AND provider = ?",
245
245
  [userId, provider]
246
246
  );
247
247
 
248
248
  // Insert new token
249
249
  await db_query(client,
250
250
  `INSERT INTO oauthtokens
251
- (ID, userid, Provider, AccessToken, RefreshToken, ExpiresAt, CreatedAt, UpdatedAt)
251
+ (id, userid, provider, accesstoken, refreshtoken, expiresat, createdat, updatedat)
252
252
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
253
253
  [tokenId, userId, provider, accessToken, refreshToken || null, expiresAt, now, now]
254
254
  );
@@ -264,7 +264,7 @@ export async function getOAuthToken(
264
264
  const client = await db_init();
265
265
 
266
266
  const tokens = await db_query(client,
267
- "SELECT * FROM oauthtokens WHERE userid = ? AND Provider = ?",
267
+ "SELECT * FROM oauthtokens WHERE userid = ? AND provider = ?",
268
268
  [userId, provider]
269
269
  );
270
270
 
@@ -285,8 +285,8 @@ export async function validateSession(sessionToken: string): Promise<{
285
285
  const sessions = await db_query(client,
286
286
  `SELECT s.*, u.* FROM usersession s
287
287
  JOIN users u ON s.userid = u.userid
288
- WHERE s.SessionToken = ? AND s.ExpirationDate > CURRENT_TIMESTAMP AND u.IsActive = ?`,
289
- [sessionToken, true]
288
+ WHERE s.sessiontoken = ? AND s.expirationdate::TIMESTAMP > CURRENT_TIMESTAMP AND u.isactive = ?`,
289
+ [sessionToken, 1] // Use 1 instead of true for PostgreSQL compatibility
290
290
  );
291
291
 
292
292
  if (!sessions || sessions.length === 0) {
@@ -296,22 +296,22 @@ export async function validateSession(sessionToken: string): Promise<{
296
296
  const session = sessions[0];
297
297
 
298
298
  // Check if session needs rotation (older than 24 hours)
299
- const sessionAge = Date.now() - new Date(session.ID).getTime();
299
+ const sessionAge = Date.now() - new Date(session.id).getTime();
300
300
  const needsRotation = sessionAge > 24 * 60 * 60 * 1000; // 24 hours
301
301
 
302
302
  return {
303
303
  valid: true,
304
304
  user: {
305
305
  userid: session.userid,
306
- OAuthID: session.OAuthID,
307
- Source: session.Source,
308
- UserName: session.UserName,
309
- Email: session.Email,
310
- AvatarURL: session.AvatarURL,
311
- UserLevel: session.UserLevel,
312
- LastLoginDate: session.LastLoginDate,
313
- CreatedDate: session.CreatedDate,
314
- IsActive: session.IsActive
306
+ oauthid: session.oauthid,
307
+ source: session.source,
308
+ username: session.username,
309
+ email: session.email,
310
+ avatarurl: session.avatarurl,
311
+ userlevel: session.userlevel,
312
+ lastlogindate: session.lastlogindate,
313
+ createddate: session.createddate,
314
+ isactive: session.isactive
315
315
  } as User,
316
316
  needsRotation
317
317
  };
@@ -325,7 +325,7 @@ export async function rotateSession(oldSessionToken: string): Promise<string | n
325
325
 
326
326
  // Get existing session
327
327
  const sessions = await db_query(client,
328
- "SELECT * FROM usersession WHERE SessionToken = ? AND ExpirationDate > CURRENT_TIMESTAMP",
328
+ "SELECT * FROM usersession WHERE sessiontoken = ? AND expirationdate::TIMESTAMP > CURRENT_TIMESTAMP",
329
329
  [oldSessionToken]
330
330
  );
331
331
 
@@ -338,8 +338,8 @@ export async function rotateSession(oldSessionToken: string): Promise<string | n
338
338
 
339
339
  // Update session with new token
340
340
  await db_query(client,
341
- "UPDATE usersession SET SessionToken = ?, ExpirationDate = ? WHERE ID = ?",
342
- [newSessionToken, new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), session.ID]
341
+ "UPDATE usersession SET sessiontoken = ?, expirationdate = ? WHERE id = ?",
342
+ [newSessionToken, new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), session.id]
343
343
  );
344
344
 
345
345
  return newSessionToken;
@@ -371,9 +371,9 @@ export async function validateOAuthToken(
371
371
  }
372
372
 
373
373
  // Check if token is expired based on stored expiry
374
- if (token.ExpiresAt && new Date(token.ExpiresAt) < new Date()) {
374
+ if (token.expiresat && new Date(token.expiresat) < new Date()) {
375
375
  // Try to refresh the token
376
- if (token.RefreshToken) {
376
+ if (token.refreshtoken) {
377
377
  return await refreshOAuthToken(userId, provider);
378
378
  }
379
379
  return false;
@@ -384,10 +384,10 @@ export async function validateOAuthToken(
384
384
  let validationUrl: string;
385
385
  switch (provider) {
386
386
  case 'google':
387
- validationUrl = `https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=${token.AccessToken}`;
387
+ validationUrl = `https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=${token.accesstoken}`;
388
388
  break;
389
389
  case 'facebook':
390
- validationUrl = `https://graph.facebook.com/me?access_token=${token.AccessToken}`;
390
+ validationUrl = `https://graph.facebook.com/me?access_token=${token.accesstoken}`;
391
391
  break;
392
392
  case 'github':
393
393
  validationUrl = 'https://api.github.com/user';
@@ -398,7 +398,7 @@ export async function validateOAuthToken(
398
398
 
399
399
  const response = await fetch(validationUrl, {
400
400
  headers: provider === 'github' ? {
401
- Authorization: `Bearer ${token.AccessToken}`
401
+ Authorization: `Bearer ${token.accesstoken}`
402
402
  } : {}
403
403
  });
404
404
 
@@ -419,7 +419,7 @@ export async function refreshOAuthToken(
419
419
 
420
420
  // Get stored OAuth token with refresh token
421
421
  const token = await getOAuthToken(userId, provider);
422
- if (!token || !token.RefreshToken) {
422
+ if (!token || !token.refreshtoken) {
423
423
  return false;
424
424
  }
425
425
 
@@ -428,7 +428,7 @@ export async function refreshOAuthToken(
428
428
 
429
429
  const params: Record<string, string> = {
430
430
  grant_type: 'refresh_token',
431
- refresh_token: token.RefreshToken,
431
+ refresh_token: token.refreshtoken,
432
432
  client_id: process.env[`NEXT_PUBLIC_${provider.toUpperCase()}_CLIENT_ID`]!,
433
433
  client_secret: process.env[`${provider.toUpperCase()}_CLIENT_SECRET`]!
434
434
  };
@@ -453,7 +453,7 @@ export async function refreshOAuthToken(
453
453
  userId,
454
454
  provider,
455
455
  data.access_token,
456
- data.refresh_token || token.RefreshToken, // Some providers don't return new refresh token
456
+ data.refresh_token || token.refreshtoken, // Some providers don't return new refresh token
457
457
  data.expires_in
458
458
  );
459
459
 
@@ -89,23 +89,21 @@ export function middleware(request: NextRequest) {
89
89
  // Using Report-Only mode to monitor CSP violations without breaking functionality
90
90
  response.headers.set('Content-Security-Policy-Report-Only', csp)
91
91
 
92
- // Add CSRF token generation for state-changing requests
93
- if (request.method !== 'GET' && request.method !== 'HEAD') {
94
- const csrfToken = request.cookies.get('csrf-token')?.value;
95
-
96
- // If no CSRF token exists, generate one
97
- if (!csrfToken) {
98
- const newCsrfToken = crypto.randomUUID();
99
- response.cookies.set({
100
- name: 'csrf-token',
101
- value: newCsrfToken,
102
- httpOnly: true,
103
- secure: process.env.NODE_ENV === 'production',
104
- sameSite: 'strict',
105
- maxAge: 60 * 60 * 24, // 24 hours
106
- path: '/'
107
- });
108
- }
92
+ // Add CSRF token generation for all requests
93
+ const csrfToken = request.cookies.get('csrf-token')?.value;
94
+
95
+ // If no CSRF token exists, generate one
96
+ if (!csrfToken) {
97
+ const newCsrfToken = crypto.randomUUID();
98
+ response.cookies.set({
99
+ name: 'csrf-token',
100
+ value: newCsrfToken,
101
+ httpOnly: true,
102
+ secure: process.env.NODE_ENV === 'production',
103
+ sameSite: 'strict',
104
+ maxAge: 60 * 60 * 24, // 24 hours
105
+ path: '/'
106
+ });
109
107
  }
110
108
 
111
109
 
@@ -5,6 +5,14 @@ import { ensureDir } from "./utils.js";
5
5
  import { fileURLToPath } from 'node:url';
6
6
  const __filename = fileURLToPath(import.meta.url);
7
7
  const __dirname = path.dirname(__filename);
8
+ /**
9
+ * Sanitizes a table name by converting to lowercase and replacing spaces with underscores
10
+ * @param name The raw table name
11
+ * @returns The sanitized table name
12
+ */
13
+ function sanitizeTableName(name) {
14
+ return name.toLowerCase().replace(/\s+/g, '_');
15
+ }
8
16
  export async function writeModelsSql(targetDir, blueprint, databaseType = "postgres") {
9
17
  const migrationsDir = path.join(targetDir, "migrations");
10
18
  ensureDir(migrationsDir);
@@ -78,7 +86,7 @@ export async function writeModelsSql(targetDir, blueprint, databaseType = "postg
78
86
  const dbTypeMap = typeMap[databaseType] || typeMap.sqlite;
79
87
  const quoteChar = databaseType === 'mysql' ? '`' : '"';
80
88
  for (const model of models) {
81
- const tableName = (model.name || model.id || "table").toLowerCase();
89
+ const tableName = sanitizeTableName(model.name || model.id || "table");
82
90
  lines.push(`\n-- Model: ${tableName}`);
83
91
  const fieldDefs = [];
84
92
  const fields = model.fields || [];
@@ -182,7 +190,7 @@ export function generateSQLFromMigrations(migrations, databaseType = "postgres")
182
190
  const sql = [];
183
191
  for (const m of migrations) {
184
192
  const action = m.action;
185
- const modelName = (m.modelName || m.modelId || "").toLowerCase();
193
+ const modelName = sanitizeTableName(m.modelName || m.modelId || "");
186
194
  if (action === "create") {
187
195
  const modelChange = m.changes.find((c) => c.type === "model" && c.operation === "add");
188
196
  const model = (modelChange?.newValue ?? { name: modelName });
@@ -200,7 +208,7 @@ export function generateSQLFromMigrations(migrations, databaseType = "postgres")
200
208
  const pk = (f.key === "primary") ? " PRIMARY KEY" : "";
201
209
  return ` ${quoteChar}${f.name.toLowerCase()}${quoteChar} ${mappedType}${required}${pk}`;
202
210
  });
203
- sql.push(`CREATE TABLE IF NOT EXISTS ${quoteChar}${(model.name || modelName).toLowerCase()}${quoteChar} (\n${fieldDefs.join(",\n")}\n);`);
211
+ sql.push(`CREATE TABLE IF NOT EXISTS ${quoteChar}${sanitizeTableName(model.name || modelName)}${quoteChar} (\n${fieldDefs.join(",\n")}\n);`);
204
212
  continue;
205
213
  }
206
214
  if (action === "delete") {