vibecodingmachine-core 2025.12.24-2348 → 2025.12.25-1541
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/package.json
CHANGED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Beta Request Management for VibeCodingMachine
|
|
3
|
+
*
|
|
4
|
+
* Handles beta access requests from web, CLI, and GUI applications
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const crypto = require('crypto');
|
|
8
|
+
|
|
9
|
+
class BetaRequestManager {
|
|
10
|
+
constructor(apiBaseUrl = null) {
|
|
11
|
+
this.apiBaseUrl = apiBaseUrl || process.env.VIBECODINGMACHINE_API_URL || 'https://api.vibecodingmachine.com';
|
|
12
|
+
this.authToken = null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Set authentication token for API requests
|
|
17
|
+
*/
|
|
18
|
+
setAuthToken(token) {
|
|
19
|
+
this.authToken = token;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Make authenticated API request
|
|
24
|
+
*/
|
|
25
|
+
async apiRequest(endpoint, options = {}) {
|
|
26
|
+
const url = `${this.apiBaseUrl}${endpoint}`;
|
|
27
|
+
const headers = {
|
|
28
|
+
'Content-Type': 'application/json',
|
|
29
|
+
...options.headers
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
if (this.authToken) {
|
|
33
|
+
headers.Authorization = `Bearer ${this.authToken}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const fetch = globalThis.fetch || require('node-fetch');
|
|
37
|
+
const response = await fetch(url, {
|
|
38
|
+
...options,
|
|
39
|
+
headers
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (!response.ok) {
|
|
43
|
+
const error = await response.json().catch(() => ({ error: 'Network error' }));
|
|
44
|
+
throw new Error(error.error || `HTTP ${response.status}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return response.json();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Submit a beta access request
|
|
52
|
+
*/
|
|
53
|
+
async submitBetaRequest(requestData) {
|
|
54
|
+
try {
|
|
55
|
+
const result = await this.apiRequest('/api/beta/request', {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
body: JSON.stringify({
|
|
58
|
+
...requestData,
|
|
59
|
+
requestDate: Date.now(),
|
|
60
|
+
status: 'REQUEST'
|
|
61
|
+
})
|
|
62
|
+
});
|
|
63
|
+
return result;
|
|
64
|
+
} catch (error) {
|
|
65
|
+
console.error('Beta request submission failed:', error);
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Check if user already has a pending or approved request
|
|
72
|
+
*/
|
|
73
|
+
async checkExistingRequest(email) {
|
|
74
|
+
try {
|
|
75
|
+
const userId = this.generateUserId(email);
|
|
76
|
+
const result = await this.apiRequest(`/api/users/${userId}`);
|
|
77
|
+
return result.user;
|
|
78
|
+
} catch (error) {
|
|
79
|
+
// User doesn't exist or API error
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Validate request data
|
|
86
|
+
*/
|
|
87
|
+
validateRequestData(data) {
|
|
88
|
+
const errors = [];
|
|
89
|
+
|
|
90
|
+
if (!data.email || !data.email.trim()) {
|
|
91
|
+
errors.push('Email is required');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (data.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(data.email)) {
|
|
95
|
+
errors.push('Invalid email format');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (!data.name || !data.name.trim()) {
|
|
99
|
+
errors.push('Name is required');
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (!data.language) {
|
|
103
|
+
errors.push('Language preference is required');
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!data.appPurpose || !data.appPurpose.trim()) {
|
|
107
|
+
errors.push('App purpose description is required');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return {
|
|
111
|
+
isValid: errors.length === 0,
|
|
112
|
+
errors
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Get supported languages
|
|
118
|
+
*/
|
|
119
|
+
getSupportedLanguages() {
|
|
120
|
+
return {
|
|
121
|
+
'en': 'English',
|
|
122
|
+
'es': 'Spanish'
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Generate user ID from email (consistent with existing system)
|
|
128
|
+
*/
|
|
129
|
+
generateUserId(email) {
|
|
130
|
+
return crypto.createHash('sha256').update(email.toLowerCase()).digest('hex').substring(0, 16);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Format request data for email notification
|
|
135
|
+
*/
|
|
136
|
+
formatRequestForEmail(requestData) {
|
|
137
|
+
const supportedLanguages = this.getSupportedLanguages();
|
|
138
|
+
const languageName = supportedLanguages[requestData.language] || requestData.language;
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
recipient: 'jesse.d.olsen@gmail.com',
|
|
142
|
+
subject: `New Beta Request: ${requestData.name} (${requestData.email})`,
|
|
143
|
+
body: `
|
|
144
|
+
New VibeCodingMachine beta access request received:
|
|
145
|
+
|
|
146
|
+
Name: ${requestData.name}
|
|
147
|
+
Email: ${requestData.email}
|
|
148
|
+
Language: ${languageName}
|
|
149
|
+
App Purpose: ${requestData.appPurpose}
|
|
150
|
+
Other Info: ${requestData.otherInfo || 'None provided'}
|
|
151
|
+
Request Date: ${new Date(requestData.requestDate).toLocaleString()}
|
|
152
|
+
Source: ${requestData.source || 'Unknown'}
|
|
153
|
+
|
|
154
|
+
Please review and approve/reject this request in the admin panel.
|
|
155
|
+
`.trim()
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
module.exports = BetaRequestManager;
|
|
@@ -228,13 +228,51 @@ class UserDatabaseClient {
|
|
|
228
228
|
throw new Error('setAdminStatus not allowed from client');
|
|
229
229
|
}
|
|
230
230
|
|
|
231
|
+
/**
|
|
232
|
+
* Submit a beta access request
|
|
233
|
+
*/
|
|
234
|
+
async submitBetaRequest(requestData) {
|
|
235
|
+
if (!this.authToken) {
|
|
236
|
+
console.warn('UserDatabase: No auth token, beta request submission requires authentication');
|
|
237
|
+
throw new Error('Authentication required for beta request');
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
const result = await this.apiRequest('/api/beta/request', {
|
|
242
|
+
method: 'POST',
|
|
243
|
+
body: JSON.stringify({
|
|
244
|
+
...requestData,
|
|
245
|
+
requestDate: Date.now(),
|
|
246
|
+
status: 'REQUEST'
|
|
247
|
+
})
|
|
248
|
+
});
|
|
249
|
+
return result;
|
|
250
|
+
} catch (error) {
|
|
251
|
+
console.warn('UserDatabase: submitBetaRequest failed:', error.message);
|
|
252
|
+
throw error;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Check if user already has a pending or approved request
|
|
258
|
+
*/
|
|
259
|
+
async checkExistingRequest(email) {
|
|
260
|
+
try {
|
|
261
|
+
const userId = this.generateUserId(email);
|
|
262
|
+
const result = await this.apiRequest(`/api/users/${userId}`);
|
|
263
|
+
return result.user;
|
|
264
|
+
} catch (error) {
|
|
265
|
+
// User doesn't exist or API error
|
|
266
|
+
return null;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
231
270
|
/**
|
|
232
271
|
* Check if user is an admin (not implemented client-side for security)
|
|
233
272
|
*/
|
|
234
273
|
async isAdmin(userId) {
|
|
235
274
|
return false; // Client-side can't check admin status
|
|
236
275
|
}
|
|
237
|
-
|
|
238
276
|
// Helper methods (same as server-side)
|
|
239
277
|
generateUserId(email) {
|
|
240
278
|
return crypto.createHash('sha256').update(email.toLowerCase()).digest('hex').substring(0, 16);
|
|
@@ -94,6 +94,20 @@ class UserDatabase {
|
|
|
94
94
|
return this.apiClient.setAdminStatus(userId, isAdmin)
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Submit a beta access request
|
|
99
|
+
*/
|
|
100
|
+
async submitBetaRequest(requestData) {
|
|
101
|
+
return this.apiClient.submitBetaRequest(requestData)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Check if user already has a pending or approved request
|
|
106
|
+
*/
|
|
107
|
+
async checkExistingRequest(email) {
|
|
108
|
+
return this.apiClient.checkExistingRequest(email)
|
|
109
|
+
}
|
|
110
|
+
|
|
97
111
|
/**
|
|
98
112
|
* Check if user is an admin
|
|
99
113
|
*/
|
package/src/sync/aws-setup.js
CHANGED
|
@@ -116,12 +116,12 @@ async function setupCognitoWithGoogle() {
|
|
|
116
116
|
|
|
117
117
|
// Add Google OAuth provider if not already configured
|
|
118
118
|
try {
|
|
119
|
-
const googleClientId = process.env.
|
|
119
|
+
const googleClientId = process.env.REACT_APP_GOOGLE_CLIENT_ID;
|
|
120
120
|
const googleClientSecret = process.env.GOOGLE_CLIENT_SECRET;
|
|
121
121
|
|
|
122
122
|
if (!googleClientId || !googleClientSecret) {
|
|
123
123
|
console.log('⚠ Google OAuth credentials not provided. Skipping Google provider setup.');
|
|
124
|
-
console.log(' Set
|
|
124
|
+
console.log(' Set REACT_APP_GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET environment variables.');
|
|
125
125
|
return { userPoolId: existingPoolId, status: 'existing' };
|
|
126
126
|
}
|
|
127
127
|
|
|
@@ -198,7 +198,7 @@ async function setupCognitoWithGoogle() {
|
|
|
198
198
|
console.log(`✓ Created Cognito User Pool: ${userPoolId}`);
|
|
199
199
|
|
|
200
200
|
// Add Google OAuth provider first (if credentials provided)
|
|
201
|
-
const googleClientId = process.env.
|
|
201
|
+
const googleClientId = process.env.REACT_APP_GOOGLE_CLIENT_ID;
|
|
202
202
|
const googleClientSecret = process.env.GOOGLE_CLIENT_SECRET;
|
|
203
203
|
|
|
204
204
|
let supportedProviders = ['COGNITO'];
|
|
@@ -231,7 +231,7 @@ async function setupCognitoWithGoogle() {
|
|
|
231
231
|
}
|
|
232
232
|
} else {
|
|
233
233
|
console.log('⚠ Google OAuth credentials not provided');
|
|
234
|
-
console.log(' Set
|
|
234
|
+
console.log(' Set REACT_APP_GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET to enable Google login');
|
|
235
235
|
}
|
|
236
236
|
|
|
237
237
|
// Create app client
|