sitepaige-mcp-server 0.7.7 → 0.7.8
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.
- package/defaultapp/api/Auth/route.ts +1 -10
- package/defaultapp/db-mysql.ts +54 -0
- package/defaultapp/db-postgres.ts +54 -0
- package/defaultapp/db-sqlite.ts +54 -0
- package/defaultapp/db-users.ts +9 -127
- package/defaultapp/db.ts +21 -0
- package/dist/defaultapp/api/Auth/route.ts +1 -10
- package/dist/defaultapp/db-mysql.ts +54 -0
- package/dist/defaultapp/db-postgres.ts +54 -0
- package/dist/defaultapp/db-sqlite.ts +54 -0
- package/dist/defaultapp/db-users.ts +9 -127
- package/dist/defaultapp/db.ts +21 -0
- package/package.json +1 -1
|
@@ -9,7 +9,7 @@ import { NextResponse } from 'next/server';
|
|
|
9
9
|
import * as crypto from 'node:crypto';
|
|
10
10
|
|
|
11
11
|
import { db_init, db_query } from '../../db';
|
|
12
|
-
import { upsertUser,
|
|
12
|
+
import { upsertUser, storeOAuthToken, validateSession, rotateSession } from '../../db-users';
|
|
13
13
|
import { validateCsrfToken } from '../../csrf';
|
|
14
14
|
|
|
15
15
|
type OAuthProvider = 'google' | 'facebook' | 'apple' | 'github';
|
|
@@ -29,9 +29,6 @@ const USER_INFO_ENDPOINTS = {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export async function POST(request: Request) {
|
|
32
|
-
// Ensure authentication tables exist
|
|
33
|
-
await ensureAuthTables();
|
|
34
|
-
|
|
35
32
|
const db = await db_init();
|
|
36
33
|
|
|
37
34
|
try {
|
|
@@ -214,9 +211,6 @@ export async function POST(request: Request) {
|
|
|
214
211
|
}
|
|
215
212
|
|
|
216
213
|
export async function GET() {
|
|
217
|
-
// Ensure authentication tables exist
|
|
218
|
-
await ensureAuthTables();
|
|
219
|
-
|
|
220
214
|
try {
|
|
221
215
|
// Get session token from cookies
|
|
222
216
|
const sessionCookie = await cookies();
|
|
@@ -308,9 +302,6 @@ export async function DELETE(request: Request) {
|
|
|
308
302
|
);
|
|
309
303
|
}
|
|
310
304
|
|
|
311
|
-
// Ensure authentication tables exist
|
|
312
|
-
await ensureAuthTables();
|
|
313
|
-
|
|
314
305
|
const db = await db_init();
|
|
315
306
|
|
|
316
307
|
try {
|
package/defaultapp/db-mysql.ts
CHANGED
|
@@ -105,6 +105,60 @@ export async function db_query(
|
|
|
105
105
|
* @returns SQL string for creating the table
|
|
106
106
|
*/
|
|
107
107
|
export function db_migrate(model: Model, dbType: string): string {
|
|
108
|
+
// Special handling for auth tables - create them first
|
|
109
|
+
if (model.name === '__auth_tables__') {
|
|
110
|
+
return `-- Users table (required for authentication)
|
|
111
|
+
CREATE TABLE IF NOT EXISTS \`Users\` (
|
|
112
|
+
\`userid\` VARCHAR(36) PRIMARY KEY DEFAULT (UUID()),
|
|
113
|
+
\`OAuthID\` VARCHAR(255) NOT NULL UNIQUE,
|
|
114
|
+
\`Source\` VARCHAR(20) NOT NULL CHECK(\`Source\` IN ('google', 'facebook', 'apple', 'github')),
|
|
115
|
+
\`UserName\` VARCHAR(255) NOT NULL,
|
|
116
|
+
\`Email\` VARCHAR(255),
|
|
117
|
+
\`AvatarURL\` TEXT,
|
|
118
|
+
\`UserLevel\` INTEGER NOT NULL DEFAULT 1 CHECK(\`UserLevel\` IN (0, 1, 2)),
|
|
119
|
+
\`UserTier\` INTEGER NOT NULL DEFAULT 0,
|
|
120
|
+
\`LastLoginDate\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
121
|
+
\`CreatedDate\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
122
|
+
\`IsActive\` BOOLEAN NOT NULL DEFAULT true
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
-- Indexes for Users table
|
|
126
|
+
CREATE INDEX idx_users_oauthid ON \`Users\`(\`OAuthID\`);
|
|
127
|
+
CREATE INDEX idx_users_email ON \`Users\`(\`Email\`);
|
|
128
|
+
CREATE INDEX idx_users_usertier ON \`Users\`(\`UserTier\`);
|
|
129
|
+
|
|
130
|
+
-- UserSession table
|
|
131
|
+
CREATE TABLE IF NOT EXISTS \`UserSession\` (
|
|
132
|
+
\`ID\` VARCHAR(36) PRIMARY KEY DEFAULT (UUID()),
|
|
133
|
+
\`SessionToken\` VARCHAR(255) NOT NULL UNIQUE,
|
|
134
|
+
\`userid\` VARCHAR(36) NOT NULL,
|
|
135
|
+
\`ExpirationDate\` DATETIME NOT NULL,
|
|
136
|
+
FOREIGN KEY (\`userid\`) REFERENCES \`Users\`(\`userid\`) ON DELETE CASCADE
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
-- Indexes for UserSession table
|
|
140
|
+
CREATE INDEX idx_session_token ON \`UserSession\`(\`SessionToken\`);
|
|
141
|
+
CREATE INDEX idx_session_user ON \`UserSession\`(\`userid\`);
|
|
142
|
+
CREATE INDEX idx_session_expiry ON \`UserSession\`(\`ExpirationDate\`);
|
|
143
|
+
|
|
144
|
+
-- OAuthTokens table
|
|
145
|
+
CREATE TABLE IF NOT EXISTS \`OAuthTokens\` (
|
|
146
|
+
\`ID\` VARCHAR(36) PRIMARY KEY DEFAULT (UUID()),
|
|
147
|
+
\`userid\` VARCHAR(36) NOT NULL,
|
|
148
|
+
\`Provider\` VARCHAR(20) NOT NULL CHECK(\`Provider\` IN ('google', 'facebook', 'apple', 'github')),
|
|
149
|
+
\`AccessToken\` TEXT NOT NULL,
|
|
150
|
+
\`RefreshToken\` TEXT,
|
|
151
|
+
\`ExpiresAt\` DATETIME,
|
|
152
|
+
\`CreatedAt\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
153
|
+
\`UpdatedAt\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
154
|
+
FOREIGN KEY (\`userid\`) REFERENCES \`Users\`(\`userid\`) ON DELETE CASCADE
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
-- Indexes for OAuthTokens table
|
|
158
|
+
CREATE INDEX idx_oauth_user ON \`OAuthTokens\`(\`userid\`);
|
|
159
|
+
CREATE INDEX idx_oauth_provider ON \`OAuthTokens\`(\`userid\`, \`Provider\`);`;
|
|
160
|
+
}
|
|
161
|
+
|
|
108
162
|
const sanitizedTableName = model.name;
|
|
109
163
|
|
|
110
164
|
// Start with the model's fields
|
|
@@ -116,6 +116,60 @@ export async function db_query(
|
|
|
116
116
|
* @returns SQL string for creating the table
|
|
117
117
|
*/
|
|
118
118
|
export function db_migrate(model: Model, dbType: string): string {
|
|
119
|
+
// Special handling for auth tables - create them first
|
|
120
|
+
if (model.name === '__auth_tables__') {
|
|
121
|
+
return `-- Users table (required for authentication)
|
|
122
|
+
CREATE TABLE IF NOT EXISTS "Users" (
|
|
123
|
+
"userid" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
124
|
+
"OAuthID" TEXT NOT NULL UNIQUE,
|
|
125
|
+
"Source" TEXT NOT NULL CHECK("Source" IN ('google', 'facebook', 'apple', 'github')),
|
|
126
|
+
"UserName" TEXT NOT NULL,
|
|
127
|
+
"Email" TEXT,
|
|
128
|
+
"AvatarURL" TEXT,
|
|
129
|
+
"UserLevel" INTEGER NOT NULL DEFAULT 1 CHECK("UserLevel" IN (0, 1, 2)),
|
|
130
|
+
"UserTier" INTEGER NOT NULL DEFAULT 0,
|
|
131
|
+
"LastLoginDate" TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
132
|
+
"CreatedDate" TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
133
|
+
"IsActive" BOOLEAN NOT NULL DEFAULT true
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
-- Indexes for Users table
|
|
137
|
+
CREATE INDEX IF NOT EXISTS idx_users_oauthid ON "Users"("OAuthID");
|
|
138
|
+
CREATE INDEX IF NOT EXISTS idx_users_email ON "Users"("Email");
|
|
139
|
+
CREATE INDEX IF NOT EXISTS idx_users_usertier ON "Users"("UserTier");
|
|
140
|
+
|
|
141
|
+
-- UserSession table
|
|
142
|
+
CREATE TABLE IF NOT EXISTS "UserSession" (
|
|
143
|
+
"ID" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
144
|
+
"SessionToken" VARCHAR(255) NOT NULL UNIQUE,
|
|
145
|
+
"userid" UUID NOT NULL,
|
|
146
|
+
"ExpirationDate" TIMESTAMP NOT NULL,
|
|
147
|
+
FOREIGN KEY ("userid") REFERENCES "Users"("userid") ON DELETE CASCADE
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
-- Indexes for UserSession table
|
|
151
|
+
CREATE INDEX IF NOT EXISTS idx_session_token ON "UserSession"("SessionToken");
|
|
152
|
+
CREATE INDEX IF NOT EXISTS idx_session_user ON "UserSession"("userid");
|
|
153
|
+
CREATE INDEX IF NOT EXISTS idx_session_expiry ON "UserSession"("ExpirationDate");
|
|
154
|
+
|
|
155
|
+
-- OAuthTokens table
|
|
156
|
+
CREATE TABLE IF NOT EXISTS "OAuthTokens" (
|
|
157
|
+
"ID" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
158
|
+
"userid" UUID NOT NULL,
|
|
159
|
+
"Provider" VARCHAR(20) NOT NULL CHECK("Provider" IN ('google', 'facebook', 'apple', 'github')),
|
|
160
|
+
"AccessToken" TEXT NOT NULL,
|
|
161
|
+
"RefreshToken" TEXT,
|
|
162
|
+
"ExpiresAt" TIMESTAMP,
|
|
163
|
+
"CreatedAt" TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
164
|
+
"UpdatedAt" TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
165
|
+
FOREIGN KEY ("userid") REFERENCES "Users"("userid") ON DELETE CASCADE
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
-- Indexes for OAuthTokens table
|
|
169
|
+
CREATE INDEX IF NOT EXISTS idx_oauth_user ON "OAuthTokens"("userid");
|
|
170
|
+
CREATE INDEX IF NOT EXISTS idx_oauth_provider ON "OAuthTokens"("userid", "Provider");`;
|
|
171
|
+
}
|
|
172
|
+
|
|
119
173
|
const sanitizedTableName = model.name;
|
|
120
174
|
|
|
121
175
|
// Start with the model's fields
|
package/defaultapp/db-sqlite.ts
CHANGED
|
@@ -181,6 +181,60 @@ export async function db_query(
|
|
|
181
181
|
* @returns SQL string for creating the table
|
|
182
182
|
*/
|
|
183
183
|
export function db_migrate(model: Model, dbType: string): string {
|
|
184
|
+
// Special handling for auth tables - create them first
|
|
185
|
+
if (model.name === '__auth_tables__') {
|
|
186
|
+
return `-- Users table (required for authentication)
|
|
187
|
+
CREATE TABLE IF NOT EXISTS "Users" (
|
|
188
|
+
"userid" TEXT PRIMARY KEY,
|
|
189
|
+
"OAuthID" TEXT NOT NULL UNIQUE,
|
|
190
|
+
"Source" TEXT NOT NULL CHECK("Source" IN ('google', 'facebook', 'apple', 'github')),
|
|
191
|
+
"UserName" TEXT NOT NULL,
|
|
192
|
+
"Email" TEXT,
|
|
193
|
+
"AvatarURL" TEXT,
|
|
194
|
+
"UserLevel" INTEGER NOT NULL DEFAULT 1 CHECK("UserLevel" IN (0, 1, 2)),
|
|
195
|
+
"UserTier" INTEGER NOT NULL DEFAULT 0,
|
|
196
|
+
"LastLoginDate" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
197
|
+
"CreatedDate" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
198
|
+
"IsActive" INTEGER NOT NULL DEFAULT 1
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
-- Indexes for Users table
|
|
202
|
+
CREATE INDEX IF NOT EXISTS idx_users_oauthid ON "Users"("OAuthID");
|
|
203
|
+
CREATE INDEX IF NOT EXISTS idx_users_email ON "Users"("Email");
|
|
204
|
+
CREATE INDEX IF NOT EXISTS idx_users_usertier ON "Users"("UserTier");
|
|
205
|
+
|
|
206
|
+
-- UserSession table
|
|
207
|
+
CREATE TABLE IF NOT EXISTS "UserSession" (
|
|
208
|
+
"ID" TEXT PRIMARY KEY,
|
|
209
|
+
"SessionToken" TEXT NOT NULL UNIQUE,
|
|
210
|
+
"userid" TEXT NOT NULL,
|
|
211
|
+
"ExpirationDate" TEXT NOT NULL,
|
|
212
|
+
FOREIGN KEY ("userid") REFERENCES "Users"("userid") ON DELETE CASCADE
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
-- Indexes for UserSession table
|
|
216
|
+
CREATE INDEX IF NOT EXISTS idx_session_token ON "UserSession"("SessionToken");
|
|
217
|
+
CREATE INDEX IF NOT EXISTS idx_session_user ON "UserSession"("userid");
|
|
218
|
+
CREATE INDEX IF NOT EXISTS idx_session_expiry ON "UserSession"("ExpirationDate");
|
|
219
|
+
|
|
220
|
+
-- OAuthTokens table
|
|
221
|
+
CREATE TABLE IF NOT EXISTS "OAuthTokens" (
|
|
222
|
+
"ID" TEXT PRIMARY KEY,
|
|
223
|
+
"userid" TEXT NOT NULL,
|
|
224
|
+
"Provider" TEXT NOT NULL CHECK("Provider" IN ('google', 'facebook', 'apple', 'github')),
|
|
225
|
+
"AccessToken" TEXT NOT NULL,
|
|
226
|
+
"RefreshToken" TEXT,
|
|
227
|
+
"ExpiresAt" TEXT,
|
|
228
|
+
"CreatedAt" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
229
|
+
"UpdatedAt" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
230
|
+
FOREIGN KEY ("userid") REFERENCES "Users"("userid") ON DELETE CASCADE
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
-- Indexes for OAuthTokens table
|
|
234
|
+
CREATE INDEX IF NOT EXISTS idx_oauth_user ON "OAuthTokens"("userid");
|
|
235
|
+
CREATE INDEX IF NOT EXISTS idx_oauth_provider ON "OAuthTokens"("userid", "Provider");`;
|
|
236
|
+
}
|
|
237
|
+
|
|
184
238
|
const sanitizedTableName = model.name;
|
|
185
239
|
|
|
186
240
|
// Start with the model's fields
|
package/defaultapp/db-users.ts
CHANGED
|
@@ -39,147 +39,29 @@ export interface OAuthToken {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
|
-
*
|
|
42
|
+
* @deprecated Table creation is now handled by db_migrate in the database implementation files
|
|
43
43
|
*/
|
|
44
44
|
export async function ensureUsersTable(): Promise<void> {
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const client = await db_init();
|
|
51
|
-
|
|
52
|
-
// Create or migrate the Users table
|
|
53
|
-
const createTableSQL = `
|
|
54
|
-
CREATE TABLE IF NOT EXISTS Users (
|
|
55
|
-
userid VARCHAR(36) PRIMARY KEY NOT NULL,
|
|
56
|
-
OAuthID VARCHAR(255) NOT NULL UNIQUE,
|
|
57
|
-
Source VARCHAR(20) NOT NULL CHECK(Source IN ('google', 'facebook', 'apple', 'github')),
|
|
58
|
-
UserName VARCHAR(255) NOT NULL,
|
|
59
|
-
Email VARCHAR(255),
|
|
60
|
-
AvatarURL TEXT,
|
|
61
|
-
UserLevel INTEGER NOT NULL DEFAULT 1 CHECK(UserLevel IN (0, 1, 2)),
|
|
62
|
-
UserTier INTEGER NOT NULL DEFAULT 0,
|
|
63
|
-
LastLoginDate DATETIME NOT NULL,
|
|
64
|
-
CreatedDate DATETIME NOT NULL,
|
|
65
|
-
IsActive BOOLEAN NOT NULL DEFAULT true
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
CREATE INDEX IF NOT EXISTS idx_users_oauth ON Users(OAuthID);
|
|
69
|
-
CREATE INDEX IF NOT EXISTS idx_users_permission ON Users(UserLevel);
|
|
70
|
-
`;
|
|
71
|
-
|
|
72
|
-
// Split and execute statements separately for compatibility
|
|
73
|
-
const statements = createTableSQL.split(';').map(s => s.trim()).filter(s => s.length > 0);
|
|
74
|
-
for (const statement of statements) {
|
|
75
|
-
try {
|
|
76
|
-
await db_query(client, statement);
|
|
77
|
-
} catch (error) {
|
|
78
|
-
// Ignore errors for index creation as some databases don't support IF NOT EXISTS for indexes
|
|
79
|
-
if (!statement.includes('CREATE INDEX')) {
|
|
80
|
-
throw error;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
45
|
+
// No longer needed - Users table is created by db_migrate
|
|
46
|
+
return;
|
|
84
47
|
}
|
|
85
48
|
|
|
86
49
|
/**
|
|
87
|
-
*
|
|
50
|
+
* @deprecated Table creation is now handled by db_migrate in the database implementation files
|
|
88
51
|
*/
|
|
89
52
|
export async function ensureUserSessionTable(): Promise<void> {
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const client = await db_init();
|
|
96
|
-
|
|
97
|
-
const createTableSQL = `
|
|
98
|
-
CREATE TABLE IF NOT EXISTS UserSession (
|
|
99
|
-
ID VARCHAR(36) PRIMARY KEY NOT NULL,
|
|
100
|
-
SessionToken VARCHAR(255) NOT NULL UNIQUE,
|
|
101
|
-
userid VARCHAR(36) NOT NULL,
|
|
102
|
-
ExpirationDate DATETIME NOT NULL,
|
|
103
|
-
FOREIGN KEY (userid) REFERENCES Users(userid) ON DELETE CASCADE
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
CREATE INDEX IF NOT EXISTS idx_session_token ON UserSession(SessionToken);
|
|
107
|
-
CREATE INDEX IF NOT EXISTS idx_session_user ON UserSession(userid);
|
|
108
|
-
CREATE INDEX IF NOT EXISTS idx_session_expiry ON UserSession(ExpirationDate);
|
|
109
|
-
`;
|
|
110
|
-
|
|
111
|
-
// Split and execute statements separately for compatibility
|
|
112
|
-
const statements = createTableSQL.split(';').map(s => s.trim()).filter(s => s.length > 0);
|
|
113
|
-
for (const statement of statements) {
|
|
114
|
-
try {
|
|
115
|
-
await db_query(client, statement);
|
|
116
|
-
} catch (error) {
|
|
117
|
-
// Ignore errors for index creation as some databases don't support IF NOT EXISTS for indexes
|
|
118
|
-
if (!statement.includes('CREATE INDEX')) {
|
|
119
|
-
throw error;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
53
|
+
// No longer needed - UserSession table is created by db_migrate
|
|
54
|
+
return;
|
|
123
55
|
}
|
|
124
56
|
|
|
125
57
|
/**
|
|
126
|
-
*
|
|
58
|
+
* @deprecated Table creation is now handled by db_migrate in the database implementation files
|
|
127
59
|
*/
|
|
128
60
|
export async function ensureOAuthTokensTable(): Promise<void> {
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const client = await db_init();
|
|
135
|
-
|
|
136
|
-
const createTableSQL = `
|
|
137
|
-
CREATE TABLE IF NOT EXISTS OAuthTokens (
|
|
138
|
-
ID VARCHAR(36) PRIMARY KEY NOT NULL,
|
|
139
|
-
userid VARCHAR(36) NOT NULL,
|
|
140
|
-
Provider VARCHAR(20) NOT NULL CHECK(Provider IN ('google', 'facebook', 'apple', 'github')),
|
|
141
|
-
AccessToken TEXT NOT NULL,
|
|
142
|
-
RefreshToken TEXT,
|
|
143
|
-
ExpiresAt DATETIME,
|
|
144
|
-
CreatedAt DATETIME NOT NULL,
|
|
145
|
-
UpdatedAt DATETIME NOT NULL,
|
|
146
|
-
FOREIGN KEY (userid) REFERENCES Users(userid) ON DELETE CASCADE
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
CREATE INDEX IF NOT EXISTS idx_oauth_user ON OAuthTokens(userid);
|
|
150
|
-
CREATE INDEX IF NOT EXISTS idx_oauth_provider ON OAuthTokens(userid, Provider);
|
|
151
|
-
`;
|
|
152
|
-
|
|
153
|
-
// Split and execute statements separately for compatibility
|
|
154
|
-
const statements = createTableSQL.split(';').map(s => s.trim()).filter(s => s.length > 0);
|
|
155
|
-
for (const statement of statements) {
|
|
156
|
-
try {
|
|
157
|
-
await db_query(client, statement);
|
|
158
|
-
} catch (error) {
|
|
159
|
-
// Ignore errors for index creation as some databases don't support IF NOT EXISTS for indexes
|
|
160
|
-
if (!statement.includes('CREATE INDEX')) {
|
|
161
|
-
throw error;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
61
|
+
// No longer needed - OAuthTokens table is created by db_migrate
|
|
62
|
+
return;
|
|
165
63
|
}
|
|
166
64
|
|
|
167
|
-
/**
|
|
168
|
-
* Ensure all authentication tables exist
|
|
169
|
-
*/
|
|
170
|
-
export async function ensureAuthTables(): Promise<void> {
|
|
171
|
-
// Skip table creation during build time
|
|
172
|
-
if (typeof window === 'undefined' && !process.env.HOSTNAME && process.env.NODE_ENV === 'production') {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const client = await db_init();
|
|
177
|
-
|
|
178
|
-
// IMPORTANT: Create Users table first since UserSession and OAuthTokens have foreign keys to it
|
|
179
|
-
await ensureUsersTable();
|
|
180
|
-
await ensureUserSessionTable();
|
|
181
|
-
await ensureOAuthTokensTable();
|
|
182
|
-
}
|
|
183
65
|
|
|
184
66
|
/**
|
|
185
67
|
* Get all users from the database
|
package/defaultapp/db.ts
CHANGED
|
@@ -158,6 +158,27 @@ export async function initializeDatabase(
|
|
|
158
158
|
const client = await db_init();
|
|
159
159
|
|
|
160
160
|
try {
|
|
161
|
+
// Create auth tables first (Users, UserSession, OAuthTokens)
|
|
162
|
+
const authTablesModel: Model = {
|
|
163
|
+
id: '__auth_tables__',
|
|
164
|
+
name: '__auth_tables__',
|
|
165
|
+
fields: []
|
|
166
|
+
};
|
|
167
|
+
const authTablesSql = db_migrate(authTablesModel);
|
|
168
|
+
|
|
169
|
+
// Execute each statement separately for auth tables
|
|
170
|
+
const authStatements = authTablesSql.split(';').map(s => s.trim()).filter(s => s.length > 0);
|
|
171
|
+
for (const statement of authStatements) {
|
|
172
|
+
try {
|
|
173
|
+
await db_query(client, statement);
|
|
174
|
+
} catch (error) {
|
|
175
|
+
// Some databases might not support certain syntax, continue with other statements
|
|
176
|
+
if (!statement.includes('CREATE INDEX')) {
|
|
177
|
+
console.error('Error creating auth table:', error);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
161
182
|
// Create tables for each model
|
|
162
183
|
for (const model of models) {
|
|
163
184
|
const createTableSql = db_migrate(model);
|
|
@@ -9,7 +9,7 @@ import { NextResponse } from 'next/server';
|
|
|
9
9
|
import * as crypto from 'node:crypto';
|
|
10
10
|
|
|
11
11
|
import { db_init, db_query } from '../../db';
|
|
12
|
-
import { upsertUser,
|
|
12
|
+
import { upsertUser, storeOAuthToken, validateSession, rotateSession } from '../../db-users';
|
|
13
13
|
import { validateCsrfToken } from '../../csrf';
|
|
14
14
|
|
|
15
15
|
type OAuthProvider = 'google' | 'facebook' | 'apple' | 'github';
|
|
@@ -29,9 +29,6 @@ const USER_INFO_ENDPOINTS = {
|
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
export async function POST(request: Request) {
|
|
32
|
-
// Ensure authentication tables exist
|
|
33
|
-
await ensureAuthTables();
|
|
34
|
-
|
|
35
32
|
const db = await db_init();
|
|
36
33
|
|
|
37
34
|
try {
|
|
@@ -214,9 +211,6 @@ export async function POST(request: Request) {
|
|
|
214
211
|
}
|
|
215
212
|
|
|
216
213
|
export async function GET() {
|
|
217
|
-
// Ensure authentication tables exist
|
|
218
|
-
await ensureAuthTables();
|
|
219
|
-
|
|
220
214
|
try {
|
|
221
215
|
// Get session token from cookies
|
|
222
216
|
const sessionCookie = await cookies();
|
|
@@ -308,9 +302,6 @@ export async function DELETE(request: Request) {
|
|
|
308
302
|
);
|
|
309
303
|
}
|
|
310
304
|
|
|
311
|
-
// Ensure authentication tables exist
|
|
312
|
-
await ensureAuthTables();
|
|
313
|
-
|
|
314
305
|
const db = await db_init();
|
|
315
306
|
|
|
316
307
|
try {
|
|
@@ -105,6 +105,60 @@ export async function db_query(
|
|
|
105
105
|
* @returns SQL string for creating the table
|
|
106
106
|
*/
|
|
107
107
|
export function db_migrate(model: Model, dbType: string): string {
|
|
108
|
+
// Special handling for auth tables - create them first
|
|
109
|
+
if (model.name === '__auth_tables__') {
|
|
110
|
+
return `-- Users table (required for authentication)
|
|
111
|
+
CREATE TABLE IF NOT EXISTS \`Users\` (
|
|
112
|
+
\`userid\` VARCHAR(36) PRIMARY KEY DEFAULT (UUID()),
|
|
113
|
+
\`OAuthID\` VARCHAR(255) NOT NULL UNIQUE,
|
|
114
|
+
\`Source\` VARCHAR(20) NOT NULL CHECK(\`Source\` IN ('google', 'facebook', 'apple', 'github')),
|
|
115
|
+
\`UserName\` VARCHAR(255) NOT NULL,
|
|
116
|
+
\`Email\` VARCHAR(255),
|
|
117
|
+
\`AvatarURL\` TEXT,
|
|
118
|
+
\`UserLevel\` INTEGER NOT NULL DEFAULT 1 CHECK(\`UserLevel\` IN (0, 1, 2)),
|
|
119
|
+
\`UserTier\` INTEGER NOT NULL DEFAULT 0,
|
|
120
|
+
\`LastLoginDate\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
121
|
+
\`CreatedDate\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
122
|
+
\`IsActive\` BOOLEAN NOT NULL DEFAULT true
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
-- Indexes for Users table
|
|
126
|
+
CREATE INDEX idx_users_oauthid ON \`Users\`(\`OAuthID\`);
|
|
127
|
+
CREATE INDEX idx_users_email ON \`Users\`(\`Email\`);
|
|
128
|
+
CREATE INDEX idx_users_usertier ON \`Users\`(\`UserTier\`);
|
|
129
|
+
|
|
130
|
+
-- UserSession table
|
|
131
|
+
CREATE TABLE IF NOT EXISTS \`UserSession\` (
|
|
132
|
+
\`ID\` VARCHAR(36) PRIMARY KEY DEFAULT (UUID()),
|
|
133
|
+
\`SessionToken\` VARCHAR(255) NOT NULL UNIQUE,
|
|
134
|
+
\`userid\` VARCHAR(36) NOT NULL,
|
|
135
|
+
\`ExpirationDate\` DATETIME NOT NULL,
|
|
136
|
+
FOREIGN KEY (\`userid\`) REFERENCES \`Users\`(\`userid\`) ON DELETE CASCADE
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
-- Indexes for UserSession table
|
|
140
|
+
CREATE INDEX idx_session_token ON \`UserSession\`(\`SessionToken\`);
|
|
141
|
+
CREATE INDEX idx_session_user ON \`UserSession\`(\`userid\`);
|
|
142
|
+
CREATE INDEX idx_session_expiry ON \`UserSession\`(\`ExpirationDate\`);
|
|
143
|
+
|
|
144
|
+
-- OAuthTokens table
|
|
145
|
+
CREATE TABLE IF NOT EXISTS \`OAuthTokens\` (
|
|
146
|
+
\`ID\` VARCHAR(36) PRIMARY KEY DEFAULT (UUID()),
|
|
147
|
+
\`userid\` VARCHAR(36) NOT NULL,
|
|
148
|
+
\`Provider\` VARCHAR(20) NOT NULL CHECK(\`Provider\` IN ('google', 'facebook', 'apple', 'github')),
|
|
149
|
+
\`AccessToken\` TEXT NOT NULL,
|
|
150
|
+
\`RefreshToken\` TEXT,
|
|
151
|
+
\`ExpiresAt\` DATETIME,
|
|
152
|
+
\`CreatedAt\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
153
|
+
\`UpdatedAt\` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
|
154
|
+
FOREIGN KEY (\`userid\`) REFERENCES \`Users\`(\`userid\`) ON DELETE CASCADE
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
-- Indexes for OAuthTokens table
|
|
158
|
+
CREATE INDEX idx_oauth_user ON \`OAuthTokens\`(\`userid\`);
|
|
159
|
+
CREATE INDEX idx_oauth_provider ON \`OAuthTokens\`(\`userid\`, \`Provider\`);`;
|
|
160
|
+
}
|
|
161
|
+
|
|
108
162
|
const sanitizedTableName = model.name;
|
|
109
163
|
|
|
110
164
|
// Start with the model's fields
|
|
@@ -116,6 +116,60 @@ export async function db_query(
|
|
|
116
116
|
* @returns SQL string for creating the table
|
|
117
117
|
*/
|
|
118
118
|
export function db_migrate(model: Model, dbType: string): string {
|
|
119
|
+
// Special handling for auth tables - create them first
|
|
120
|
+
if (model.name === '__auth_tables__') {
|
|
121
|
+
return `-- Users table (required for authentication)
|
|
122
|
+
CREATE TABLE IF NOT EXISTS "Users" (
|
|
123
|
+
"userid" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
124
|
+
"OAuthID" TEXT NOT NULL UNIQUE,
|
|
125
|
+
"Source" TEXT NOT NULL CHECK("Source" IN ('google', 'facebook', 'apple', 'github')),
|
|
126
|
+
"UserName" TEXT NOT NULL,
|
|
127
|
+
"Email" TEXT,
|
|
128
|
+
"AvatarURL" TEXT,
|
|
129
|
+
"UserLevel" INTEGER NOT NULL DEFAULT 1 CHECK("UserLevel" IN (0, 1, 2)),
|
|
130
|
+
"UserTier" INTEGER NOT NULL DEFAULT 0,
|
|
131
|
+
"LastLoginDate" TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
132
|
+
"CreatedDate" TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
133
|
+
"IsActive" BOOLEAN NOT NULL DEFAULT true
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
-- Indexes for Users table
|
|
137
|
+
CREATE INDEX IF NOT EXISTS idx_users_oauthid ON "Users"("OAuthID");
|
|
138
|
+
CREATE INDEX IF NOT EXISTS idx_users_email ON "Users"("Email");
|
|
139
|
+
CREATE INDEX IF NOT EXISTS idx_users_usertier ON "Users"("UserTier");
|
|
140
|
+
|
|
141
|
+
-- UserSession table
|
|
142
|
+
CREATE TABLE IF NOT EXISTS "UserSession" (
|
|
143
|
+
"ID" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
144
|
+
"SessionToken" VARCHAR(255) NOT NULL UNIQUE,
|
|
145
|
+
"userid" UUID NOT NULL,
|
|
146
|
+
"ExpirationDate" TIMESTAMP NOT NULL,
|
|
147
|
+
FOREIGN KEY ("userid") REFERENCES "Users"("userid") ON DELETE CASCADE
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
-- Indexes for UserSession table
|
|
151
|
+
CREATE INDEX IF NOT EXISTS idx_session_token ON "UserSession"("SessionToken");
|
|
152
|
+
CREATE INDEX IF NOT EXISTS idx_session_user ON "UserSession"("userid");
|
|
153
|
+
CREATE INDEX IF NOT EXISTS idx_session_expiry ON "UserSession"("ExpirationDate");
|
|
154
|
+
|
|
155
|
+
-- OAuthTokens table
|
|
156
|
+
CREATE TABLE IF NOT EXISTS "OAuthTokens" (
|
|
157
|
+
"ID" UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
158
|
+
"userid" UUID NOT NULL,
|
|
159
|
+
"Provider" VARCHAR(20) NOT NULL CHECK("Provider" IN ('google', 'facebook', 'apple', 'github')),
|
|
160
|
+
"AccessToken" TEXT NOT NULL,
|
|
161
|
+
"RefreshToken" TEXT,
|
|
162
|
+
"ExpiresAt" TIMESTAMP,
|
|
163
|
+
"CreatedAt" TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
164
|
+
"UpdatedAt" TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
165
|
+
FOREIGN KEY ("userid") REFERENCES "Users"("userid") ON DELETE CASCADE
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
-- Indexes for OAuthTokens table
|
|
169
|
+
CREATE INDEX IF NOT EXISTS idx_oauth_user ON "OAuthTokens"("userid");
|
|
170
|
+
CREATE INDEX IF NOT EXISTS idx_oauth_provider ON "OAuthTokens"("userid", "Provider");`;
|
|
171
|
+
}
|
|
172
|
+
|
|
119
173
|
const sanitizedTableName = model.name;
|
|
120
174
|
|
|
121
175
|
// Start with the model's fields
|
|
@@ -181,6 +181,60 @@ export async function db_query(
|
|
|
181
181
|
* @returns SQL string for creating the table
|
|
182
182
|
*/
|
|
183
183
|
export function db_migrate(model: Model, dbType: string): string {
|
|
184
|
+
// Special handling for auth tables - create them first
|
|
185
|
+
if (model.name === '__auth_tables__') {
|
|
186
|
+
return `-- Users table (required for authentication)
|
|
187
|
+
CREATE TABLE IF NOT EXISTS "Users" (
|
|
188
|
+
"userid" TEXT PRIMARY KEY,
|
|
189
|
+
"OAuthID" TEXT NOT NULL UNIQUE,
|
|
190
|
+
"Source" TEXT NOT NULL CHECK("Source" IN ('google', 'facebook', 'apple', 'github')),
|
|
191
|
+
"UserName" TEXT NOT NULL,
|
|
192
|
+
"Email" TEXT,
|
|
193
|
+
"AvatarURL" TEXT,
|
|
194
|
+
"UserLevel" INTEGER NOT NULL DEFAULT 1 CHECK("UserLevel" IN (0, 1, 2)),
|
|
195
|
+
"UserTier" INTEGER NOT NULL DEFAULT 0,
|
|
196
|
+
"LastLoginDate" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
197
|
+
"CreatedDate" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
198
|
+
"IsActive" INTEGER NOT NULL DEFAULT 1
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
-- Indexes for Users table
|
|
202
|
+
CREATE INDEX IF NOT EXISTS idx_users_oauthid ON "Users"("OAuthID");
|
|
203
|
+
CREATE INDEX IF NOT EXISTS idx_users_email ON "Users"("Email");
|
|
204
|
+
CREATE INDEX IF NOT EXISTS idx_users_usertier ON "Users"("UserTier");
|
|
205
|
+
|
|
206
|
+
-- UserSession table
|
|
207
|
+
CREATE TABLE IF NOT EXISTS "UserSession" (
|
|
208
|
+
"ID" TEXT PRIMARY KEY,
|
|
209
|
+
"SessionToken" TEXT NOT NULL UNIQUE,
|
|
210
|
+
"userid" TEXT NOT NULL,
|
|
211
|
+
"ExpirationDate" TEXT NOT NULL,
|
|
212
|
+
FOREIGN KEY ("userid") REFERENCES "Users"("userid") ON DELETE CASCADE
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
-- Indexes for UserSession table
|
|
216
|
+
CREATE INDEX IF NOT EXISTS idx_session_token ON "UserSession"("SessionToken");
|
|
217
|
+
CREATE INDEX IF NOT EXISTS idx_session_user ON "UserSession"("userid");
|
|
218
|
+
CREATE INDEX IF NOT EXISTS idx_session_expiry ON "UserSession"("ExpirationDate");
|
|
219
|
+
|
|
220
|
+
-- OAuthTokens table
|
|
221
|
+
CREATE TABLE IF NOT EXISTS "OAuthTokens" (
|
|
222
|
+
"ID" TEXT PRIMARY KEY,
|
|
223
|
+
"userid" TEXT NOT NULL,
|
|
224
|
+
"Provider" TEXT NOT NULL CHECK("Provider" IN ('google', 'facebook', 'apple', 'github')),
|
|
225
|
+
"AccessToken" TEXT NOT NULL,
|
|
226
|
+
"RefreshToken" TEXT,
|
|
227
|
+
"ExpiresAt" TEXT,
|
|
228
|
+
"CreatedAt" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
229
|
+
"UpdatedAt" TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
230
|
+
FOREIGN KEY ("userid") REFERENCES "Users"("userid") ON DELETE CASCADE
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
-- Indexes for OAuthTokens table
|
|
234
|
+
CREATE INDEX IF NOT EXISTS idx_oauth_user ON "OAuthTokens"("userid");
|
|
235
|
+
CREATE INDEX IF NOT EXISTS idx_oauth_provider ON "OAuthTokens"("userid", "Provider");`;
|
|
236
|
+
}
|
|
237
|
+
|
|
184
238
|
const sanitizedTableName = model.name;
|
|
185
239
|
|
|
186
240
|
// Start with the model's fields
|
|
@@ -39,147 +39,29 @@ export interface OAuthToken {
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
|
-
*
|
|
42
|
+
* @deprecated Table creation is now handled by db_migrate in the database implementation files
|
|
43
43
|
*/
|
|
44
44
|
export async function ensureUsersTable(): Promise<void> {
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const client = await db_init();
|
|
51
|
-
|
|
52
|
-
// Create or migrate the Users table
|
|
53
|
-
const createTableSQL = `
|
|
54
|
-
CREATE TABLE IF NOT EXISTS Users (
|
|
55
|
-
userid VARCHAR(36) PRIMARY KEY NOT NULL,
|
|
56
|
-
OAuthID VARCHAR(255) NOT NULL UNIQUE,
|
|
57
|
-
Source VARCHAR(20) NOT NULL CHECK(Source IN ('google', 'facebook', 'apple', 'github')),
|
|
58
|
-
UserName VARCHAR(255) NOT NULL,
|
|
59
|
-
Email VARCHAR(255),
|
|
60
|
-
AvatarURL TEXT,
|
|
61
|
-
UserLevel INTEGER NOT NULL DEFAULT 1 CHECK(UserLevel IN (0, 1, 2)),
|
|
62
|
-
UserTier INTEGER NOT NULL DEFAULT 0,
|
|
63
|
-
LastLoginDate DATETIME NOT NULL,
|
|
64
|
-
CreatedDate DATETIME NOT NULL,
|
|
65
|
-
IsActive BOOLEAN NOT NULL DEFAULT true
|
|
66
|
-
);
|
|
67
|
-
|
|
68
|
-
CREATE INDEX IF NOT EXISTS idx_users_oauth ON Users(OAuthID);
|
|
69
|
-
CREATE INDEX IF NOT EXISTS idx_users_permission ON Users(UserLevel);
|
|
70
|
-
`;
|
|
71
|
-
|
|
72
|
-
// Split and execute statements separately for compatibility
|
|
73
|
-
const statements = createTableSQL.split(';').map(s => s.trim()).filter(s => s.length > 0);
|
|
74
|
-
for (const statement of statements) {
|
|
75
|
-
try {
|
|
76
|
-
await db_query(client, statement);
|
|
77
|
-
} catch (error) {
|
|
78
|
-
// Ignore errors for index creation as some databases don't support IF NOT EXISTS for indexes
|
|
79
|
-
if (!statement.includes('CREATE INDEX')) {
|
|
80
|
-
throw error;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
45
|
+
// No longer needed - Users table is created by db_migrate
|
|
46
|
+
return;
|
|
84
47
|
}
|
|
85
48
|
|
|
86
49
|
/**
|
|
87
|
-
*
|
|
50
|
+
* @deprecated Table creation is now handled by db_migrate in the database implementation files
|
|
88
51
|
*/
|
|
89
52
|
export async function ensureUserSessionTable(): Promise<void> {
|
|
90
|
-
//
|
|
91
|
-
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const client = await db_init();
|
|
96
|
-
|
|
97
|
-
const createTableSQL = `
|
|
98
|
-
CREATE TABLE IF NOT EXISTS UserSession (
|
|
99
|
-
ID VARCHAR(36) PRIMARY KEY NOT NULL,
|
|
100
|
-
SessionToken VARCHAR(255) NOT NULL UNIQUE,
|
|
101
|
-
userid VARCHAR(36) NOT NULL,
|
|
102
|
-
ExpirationDate DATETIME NOT NULL,
|
|
103
|
-
FOREIGN KEY (userid) REFERENCES Users(userid) ON DELETE CASCADE
|
|
104
|
-
);
|
|
105
|
-
|
|
106
|
-
CREATE INDEX IF NOT EXISTS idx_session_token ON UserSession(SessionToken);
|
|
107
|
-
CREATE INDEX IF NOT EXISTS idx_session_user ON UserSession(userid);
|
|
108
|
-
CREATE INDEX IF NOT EXISTS idx_session_expiry ON UserSession(ExpirationDate);
|
|
109
|
-
`;
|
|
110
|
-
|
|
111
|
-
// Split and execute statements separately for compatibility
|
|
112
|
-
const statements = createTableSQL.split(';').map(s => s.trim()).filter(s => s.length > 0);
|
|
113
|
-
for (const statement of statements) {
|
|
114
|
-
try {
|
|
115
|
-
await db_query(client, statement);
|
|
116
|
-
} catch (error) {
|
|
117
|
-
// Ignore errors for index creation as some databases don't support IF NOT EXISTS for indexes
|
|
118
|
-
if (!statement.includes('CREATE INDEX')) {
|
|
119
|
-
throw error;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
53
|
+
// No longer needed - UserSession table is created by db_migrate
|
|
54
|
+
return;
|
|
123
55
|
}
|
|
124
56
|
|
|
125
57
|
/**
|
|
126
|
-
*
|
|
58
|
+
* @deprecated Table creation is now handled by db_migrate in the database implementation files
|
|
127
59
|
*/
|
|
128
60
|
export async function ensureOAuthTokensTable(): Promise<void> {
|
|
129
|
-
//
|
|
130
|
-
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const client = await db_init();
|
|
135
|
-
|
|
136
|
-
const createTableSQL = `
|
|
137
|
-
CREATE TABLE IF NOT EXISTS OAuthTokens (
|
|
138
|
-
ID VARCHAR(36) PRIMARY KEY NOT NULL,
|
|
139
|
-
userid VARCHAR(36) NOT NULL,
|
|
140
|
-
Provider VARCHAR(20) NOT NULL CHECK(Provider IN ('google', 'facebook', 'apple', 'github')),
|
|
141
|
-
AccessToken TEXT NOT NULL,
|
|
142
|
-
RefreshToken TEXT,
|
|
143
|
-
ExpiresAt DATETIME,
|
|
144
|
-
CreatedAt DATETIME NOT NULL,
|
|
145
|
-
UpdatedAt DATETIME NOT NULL,
|
|
146
|
-
FOREIGN KEY (userid) REFERENCES Users(userid) ON DELETE CASCADE
|
|
147
|
-
);
|
|
148
|
-
|
|
149
|
-
CREATE INDEX IF NOT EXISTS idx_oauth_user ON OAuthTokens(userid);
|
|
150
|
-
CREATE INDEX IF NOT EXISTS idx_oauth_provider ON OAuthTokens(userid, Provider);
|
|
151
|
-
`;
|
|
152
|
-
|
|
153
|
-
// Split and execute statements separately for compatibility
|
|
154
|
-
const statements = createTableSQL.split(';').map(s => s.trim()).filter(s => s.length > 0);
|
|
155
|
-
for (const statement of statements) {
|
|
156
|
-
try {
|
|
157
|
-
await db_query(client, statement);
|
|
158
|
-
} catch (error) {
|
|
159
|
-
// Ignore errors for index creation as some databases don't support IF NOT EXISTS for indexes
|
|
160
|
-
if (!statement.includes('CREATE INDEX')) {
|
|
161
|
-
throw error;
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
}
|
|
61
|
+
// No longer needed - OAuthTokens table is created by db_migrate
|
|
62
|
+
return;
|
|
165
63
|
}
|
|
166
64
|
|
|
167
|
-
/**
|
|
168
|
-
* Ensure all authentication tables exist
|
|
169
|
-
*/
|
|
170
|
-
export async function ensureAuthTables(): Promise<void> {
|
|
171
|
-
// Skip table creation during build time
|
|
172
|
-
if (typeof window === 'undefined' && !process.env.HOSTNAME && process.env.NODE_ENV === 'production') {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const client = await db_init();
|
|
177
|
-
|
|
178
|
-
// IMPORTANT: Create Users table first since UserSession and OAuthTokens have foreign keys to it
|
|
179
|
-
await ensureUsersTable();
|
|
180
|
-
await ensureUserSessionTable();
|
|
181
|
-
await ensureOAuthTokensTable();
|
|
182
|
-
}
|
|
183
65
|
|
|
184
66
|
/**
|
|
185
67
|
* Get all users from the database
|
package/dist/defaultapp/db.ts
CHANGED
|
@@ -158,6 +158,27 @@ export async function initializeDatabase(
|
|
|
158
158
|
const client = await db_init();
|
|
159
159
|
|
|
160
160
|
try {
|
|
161
|
+
// Create auth tables first (Users, UserSession, OAuthTokens)
|
|
162
|
+
const authTablesModel: Model = {
|
|
163
|
+
id: '__auth_tables__',
|
|
164
|
+
name: '__auth_tables__',
|
|
165
|
+
fields: []
|
|
166
|
+
};
|
|
167
|
+
const authTablesSql = db_migrate(authTablesModel);
|
|
168
|
+
|
|
169
|
+
// Execute each statement separately for auth tables
|
|
170
|
+
const authStatements = authTablesSql.split(';').map(s => s.trim()).filter(s => s.length > 0);
|
|
171
|
+
for (const statement of authStatements) {
|
|
172
|
+
try {
|
|
173
|
+
await db_query(client, statement);
|
|
174
|
+
} catch (error) {
|
|
175
|
+
// Some databases might not support certain syntax, continue with other statements
|
|
176
|
+
if (!statement.includes('CREATE INDEX')) {
|
|
177
|
+
console.error('Error creating auth table:', error);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
161
182
|
// Create tables for each model
|
|
162
183
|
for (const model of models) {
|
|
163
184
|
const createTableSql = db_migrate(model);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sitepaige-mcp-server",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MCP server for generating web applications using SitePaige AI. Generate frontend (FREE/12 credits) then optionally add backend (50 credits)",
|
|
6
6
|
"keywords": [
|