create-prisma-php-app 1.11.543 → 1.11.601
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/composer.json +2 -1
- package/dist/bootstrap.php +170 -63
- package/dist/index.js +53 -32
- package/dist/prisma/schema.prisma +2 -0
- package/dist/prisma-client-php/index.enc +1 -1
- package/dist/prisma-php.js +161 -100
- package/dist/settings/public-functions.php +7 -0
- package/dist/src/Lib/Auth/Auth.php +236 -2
- package/dist/src/Lib/FormHandler.php +308 -0
- package/dist/src/Lib/Middleware/AuthMiddleware.php +1 -1
- package/dist/src/Lib/PHPMailer/Mailer.php +5 -8
- package/dist/src/Lib/StateManager.php +1 -1
- package/dist/src/Lib/Validator.php +28 -0
- package/dist/src/app/index.php +2 -2
- package/dist/tsconfig.json +3 -1
- package/package.json +1 -1
- package/dist/.env +0 -0
package/dist/prisma-php.js
CHANGED
|
@@ -1,100 +1,161 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import chalk from
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import chalk from "chalk";
|
|
3
|
+
import { spawn } from "child_process";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import prompts from "prompts";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
const readJsonFile = (filePath) => {
|
|
12
|
+
const jsonData = fs.readFileSync(filePath, "utf8");
|
|
13
|
+
return JSON.parse(jsonData);
|
|
14
|
+
};
|
|
15
|
+
const executeCommand = (command, args = [], options = {}) => {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const process = spawn(
|
|
18
|
+
command,
|
|
19
|
+
args,
|
|
20
|
+
Object.assign({ stdio: "inherit", shell: true }, options)
|
|
21
|
+
);
|
|
22
|
+
process.on("error", (error) => {
|
|
23
|
+
console.error(`Execution error: ${error.message}`);
|
|
24
|
+
reject(error);
|
|
25
|
+
});
|
|
26
|
+
process.on("close", (code) => {
|
|
27
|
+
if (code === 0) {
|
|
28
|
+
resolve();
|
|
29
|
+
} else {
|
|
30
|
+
reject(new Error(`Process exited with code ${code}`));
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
async function getAnswer() {
|
|
36
|
+
const questions = [
|
|
37
|
+
{
|
|
38
|
+
type: "toggle",
|
|
39
|
+
name: "shouldProceed",
|
|
40
|
+
message: `This command will update the ${chalk.blue(
|
|
41
|
+
"create-prisma-php-app"
|
|
42
|
+
)} package and overwrite all default files. ${chalk.blue(
|
|
43
|
+
"Do you want to proceed"
|
|
44
|
+
)}?`,
|
|
45
|
+
initial: false,
|
|
46
|
+
active: "Yes",
|
|
47
|
+
inactive: "No",
|
|
48
|
+
},
|
|
49
|
+
];
|
|
50
|
+
const onCancel = () => {
|
|
51
|
+
console.log(chalk.red("Operation cancelled by the user."));
|
|
52
|
+
process.exit(0);
|
|
53
|
+
};
|
|
54
|
+
const response = await prompts(questions, { onCancel });
|
|
55
|
+
if (Object.keys(response).length === 0) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return response;
|
|
59
|
+
}
|
|
60
|
+
const commandsToExecute = {
|
|
61
|
+
generateClass: "npx php generate class",
|
|
62
|
+
update: "npx php update project",
|
|
63
|
+
};
|
|
64
|
+
const main = async () => {
|
|
65
|
+
if (args.length === 0) {
|
|
66
|
+
console.log("No command provided.");
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const formattedCommand = `npx php ${args.join(" ")}`;
|
|
70
|
+
const commandsArray = Object.values(commandsToExecute);
|
|
71
|
+
if (!commandsArray.includes(formattedCommand)) {
|
|
72
|
+
console.log("Command not recognized or not allowed.");
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (formattedCommand === commandsToExecute.update) {
|
|
76
|
+
try {
|
|
77
|
+
const answer = await getAnswer();
|
|
78
|
+
if (
|
|
79
|
+
!(answer === null || answer === void 0 ? void 0 : answer.shouldProceed)
|
|
80
|
+
) {
|
|
81
|
+
console.log(chalk.red("Operation cancelled by the user."));
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const currentDir = process.cwd();
|
|
85
|
+
const configPath = path.join(currentDir, "prisma-php.json");
|
|
86
|
+
if (!fs.existsSync(configPath)) {
|
|
87
|
+
console.error(
|
|
88
|
+
chalk.red(
|
|
89
|
+
"The configuration file 'prisma-php.json' was not found in the current directory."
|
|
90
|
+
)
|
|
91
|
+
);
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
const localSettings = readJsonFile(configPath);
|
|
95
|
+
const commandArgs = [localSettings.projectName];
|
|
96
|
+
if (localSettings.tailwindcss) commandArgs.push("--tailwindcss");
|
|
97
|
+
if (localSettings.websocket) commandArgs.push("--websocket");
|
|
98
|
+
if (localSettings.prisma) commandArgs.push("--prisma");
|
|
99
|
+
console.log("Executing command...\n");
|
|
100
|
+
await executeCommand("npx", [
|
|
101
|
+
"create-prisma-php-app@test-update",
|
|
102
|
+
...commandArgs,
|
|
103
|
+
]);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
if (error instanceof Error) {
|
|
106
|
+
if (error.message.includes("no such file or directory")) {
|
|
107
|
+
console.error(
|
|
108
|
+
chalk.red(
|
|
109
|
+
"The configuration file 'prisma-php.json' was not found in the current directory."
|
|
110
|
+
)
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
console.error("Error in script execution:", error);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (formattedCommand === commandsToExecute.generateClass) {
|
|
119
|
+
try {
|
|
120
|
+
const currentDir = process.cwd();
|
|
121
|
+
const configPath = path.join(currentDir, "prisma-php.json");
|
|
122
|
+
if (!fs.existsSync(configPath)) {
|
|
123
|
+
console.error(
|
|
124
|
+
chalk.red(
|
|
125
|
+
"The configuration file 'prisma-php.json' was not found in the current directory."
|
|
126
|
+
)
|
|
127
|
+
);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
const localSettings = readJsonFile(configPath);
|
|
131
|
+
if (!localSettings.prisma) {
|
|
132
|
+
console.error(
|
|
133
|
+
chalk.red(
|
|
134
|
+
"Install the 'Prisma PHP ORM' package by running the command 'npx php update project'."
|
|
135
|
+
)
|
|
136
|
+
);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const prismaClientPath = path.join(
|
|
140
|
+
__dirname,
|
|
141
|
+
"prisma-client-php",
|
|
142
|
+
"index.js"
|
|
143
|
+
);
|
|
144
|
+
if (!fs.existsSync(prismaClientPath)) {
|
|
145
|
+
console.error(
|
|
146
|
+
chalk.red(
|
|
147
|
+
"The 'prisma-client-php' package was not found in the current directory."
|
|
148
|
+
)
|
|
149
|
+
);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
console.log("Executing command...\n");
|
|
153
|
+
await executeCommand("node", [prismaClientPath]);
|
|
154
|
+
} catch (error) {
|
|
155
|
+
console.error("Error in script execution:", error);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
main().catch((error) => {
|
|
160
|
+
console.error("Unhandled error in main function:", error);
|
|
161
|
+
});
|
|
@@ -6,12 +6,17 @@ use Firebase\JWT\JWT;
|
|
|
6
6
|
use Firebase\JWT\Key;
|
|
7
7
|
use DateInterval;
|
|
8
8
|
use DateTime;
|
|
9
|
+
use Lib\Validator;
|
|
10
|
+
use GuzzleHttp\Client;
|
|
11
|
+
use GuzzleHttp\Exception\RequestException;
|
|
9
12
|
|
|
10
13
|
class Auth
|
|
11
14
|
{
|
|
12
15
|
public const PAYLOAD_NAME = 'role';
|
|
13
|
-
public const
|
|
14
|
-
public const
|
|
16
|
+
public const ROLE_NAME = '';
|
|
17
|
+
public const PAYLOAD = 'payload_2183A';
|
|
18
|
+
public const COOKIE_NAME = 'pphp_aut_token_D36E5';
|
|
19
|
+
private const PPHPAUTH = 'pphpauth';
|
|
15
20
|
|
|
16
21
|
private $secretKey;
|
|
17
22
|
private $defaultTokenValidity = '1h'; // Default to 1 hour
|
|
@@ -181,4 +186,233 @@ class Auth
|
|
|
181
186
|
|
|
182
187
|
return null;
|
|
183
188
|
}
|
|
189
|
+
|
|
190
|
+
private function exchangeCode($data, $apiUrl)
|
|
191
|
+
{
|
|
192
|
+
try {
|
|
193
|
+
$client = new Client();
|
|
194
|
+
$response = $client->post($apiUrl, [
|
|
195
|
+
'headers' => [
|
|
196
|
+
'Accept' => 'application/json',
|
|
197
|
+
],
|
|
198
|
+
'form_params' => $data,
|
|
199
|
+
]);
|
|
200
|
+
|
|
201
|
+
if ($response->getStatusCode() === 200) {
|
|
202
|
+
return json_decode($response->getBody()->getContents());
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return false;
|
|
206
|
+
} catch (RequestException) {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
private function saveAuthInfo($responseInfo, $accountData)
|
|
212
|
+
{
|
|
213
|
+
// Save user data to the database
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
private function findProvider(array $providers, string $type): ?object
|
|
217
|
+
{
|
|
218
|
+
foreach ($providers as $provider) {
|
|
219
|
+
if ($provider instanceof $type) {
|
|
220
|
+
return $provider;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
public function authProviders(...$providers)
|
|
227
|
+
{
|
|
228
|
+
global $isGet, $dynamicRouteParams;
|
|
229
|
+
|
|
230
|
+
if ($isGet && in_array('signin', $dynamicRouteParams[self::PPHPAUTH])) {
|
|
231
|
+
foreach ($providers as $provider) {
|
|
232
|
+
if ($provider instanceof GithubProvider && in_array('github', $dynamicRouteParams[self::PPHPAUTH])) {
|
|
233
|
+
$githubAuthUrl = "https://github.com/login/oauth/authorize?scope=user:email%20read:user&client_id={$provider->clientId}";
|
|
234
|
+
redirect($githubAuthUrl);
|
|
235
|
+
} elseif ($provider instanceof GoogleProvider && in_array('google', $dynamicRouteParams[self::PPHPAUTH])) {
|
|
236
|
+
$googleAuthUrl = "https://accounts.google.com/o/oauth2/v2/auth?"
|
|
237
|
+
. "scope=" . urlencode('email profile') . "&"
|
|
238
|
+
. "response_type=code&"
|
|
239
|
+
. "client_id=" . urlencode($provider->clientId) . "&"
|
|
240
|
+
. "redirect_uri=" . urlencode($provider->redirectUri);
|
|
241
|
+
redirect($googleAuthUrl);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
$authCode = Validator::validateString($_GET['code'] ?? '');
|
|
247
|
+
|
|
248
|
+
if ($isGet && in_array('callback', $dynamicRouteParams[self::PPHPAUTH]) && isset($authCode)) {
|
|
249
|
+
if (in_array('github', $dynamicRouteParams[self::PPHPAUTH])) {
|
|
250
|
+
$provider = $this->findProvider($providers, GithubProvider::class);
|
|
251
|
+
|
|
252
|
+
if (!$provider) {
|
|
253
|
+
exit("Error occurred. Please try again.");
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return $this->githubProvider($provider, $authCode);
|
|
257
|
+
} elseif (in_array('google', $dynamicRouteParams[self::PPHPAUTH])) {
|
|
258
|
+
$provider = $this->findProvider($providers, GoogleProvider::class);
|
|
259
|
+
|
|
260
|
+
if (!$provider) {
|
|
261
|
+
exit("Error occurred. Please try again.");
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return $this->googleProvider($provider, $authCode);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
exit("Error occurred. Please try again.");
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
private function githubProvider(GithubProvider $githubProvider, string $authCode)
|
|
272
|
+
{
|
|
273
|
+
$gitToken = [
|
|
274
|
+
'client_id' => $githubProvider->clientId,
|
|
275
|
+
'client_secret' => $githubProvider->clientSecret,
|
|
276
|
+
'code' => $authCode,
|
|
277
|
+
];
|
|
278
|
+
|
|
279
|
+
$apiUrl = 'https://github.com/login/oauth/access_token';
|
|
280
|
+
$tokenData = (object)$this->exchangeCode($gitToken, $apiUrl);
|
|
281
|
+
|
|
282
|
+
if (!$tokenData) {
|
|
283
|
+
exit("Error occurred. Please try again.");
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (isset($tokenData->error)) {
|
|
287
|
+
exit("Error occurred. Please try again.");
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (isset($tokenData->access_token)) {
|
|
291
|
+
$client = new Client();
|
|
292
|
+
$emailResponse = $client->get('https://api.github.com/user/emails', [
|
|
293
|
+
'headers' => [
|
|
294
|
+
'Authorization' => 'Bearer ' . $tokenData->access_token,
|
|
295
|
+
'Accept' => 'application/json',
|
|
296
|
+
],
|
|
297
|
+
]);
|
|
298
|
+
|
|
299
|
+
$emails = json_decode($emailResponse->getBody()->getContents(), true);
|
|
300
|
+
|
|
301
|
+
$primaryEmail = array_reduce($emails, function ($carry, $item) {
|
|
302
|
+
return ($item['primary'] && $item['verified']) ? $item['email'] : $carry;
|
|
303
|
+
}, null);
|
|
304
|
+
|
|
305
|
+
$response = $client->get('https://api.github.com/user', [
|
|
306
|
+
'headers' => [
|
|
307
|
+
'Accept' => 'application/json',
|
|
308
|
+
'Authorization' => 'Bearer ' . $tokenData->access_token,
|
|
309
|
+
],
|
|
310
|
+
]);
|
|
311
|
+
|
|
312
|
+
if ($response->getStatusCode() == 200) {
|
|
313
|
+
$responseInfo = json_decode($response->getBody()->getContents());
|
|
314
|
+
|
|
315
|
+
$accountData = [
|
|
316
|
+
'provider' => 'github',
|
|
317
|
+
'type' => 'oauth',
|
|
318
|
+
'providerAccountId' => "$responseInfo->id",
|
|
319
|
+
'access_token' => $tokenData->access_token,
|
|
320
|
+
'expires_at' => $tokenData->expires_at ?? null,
|
|
321
|
+
'token_type' => $tokenData->token_type,
|
|
322
|
+
'scope' => $tokenData->scope,
|
|
323
|
+
];
|
|
324
|
+
|
|
325
|
+
$this->saveAuthInfo($responseInfo, $accountData);
|
|
326
|
+
|
|
327
|
+
$userToAuthenticate = [
|
|
328
|
+
'name' => $responseInfo->login,
|
|
329
|
+
'email' => $primaryEmail,
|
|
330
|
+
'image' => $responseInfo->avatar_url,
|
|
331
|
+
'Account' => (object)$accountData
|
|
332
|
+
];
|
|
333
|
+
$userToAuthenticate = (object)$userToAuthenticate;
|
|
334
|
+
|
|
335
|
+
$this->authenticate($userToAuthenticate, $githubProvider->maxAge);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
private function googleProvider(GoogleProvider $googleProvider, string $authCode)
|
|
341
|
+
{
|
|
342
|
+
$googleToken = [
|
|
343
|
+
'client_id' => $googleProvider->clientId,
|
|
344
|
+
'client_secret' => $googleProvider->clientSecret,
|
|
345
|
+
'code' => $authCode,
|
|
346
|
+
'grant_type' => 'authorization_code',
|
|
347
|
+
'redirect_uri' => $googleProvider->redirectUri
|
|
348
|
+
];
|
|
349
|
+
|
|
350
|
+
$apiUrl = 'https://oauth2.googleapis.com/token';
|
|
351
|
+
$tokenData = (object)$this->exchangeCode($googleToken, $apiUrl);
|
|
352
|
+
|
|
353
|
+
if (!$tokenData) {
|
|
354
|
+
exit("Error occurred. Please try again.");
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
if (isset($tokenData->error)) {
|
|
358
|
+
exit("Error occurred. Please try again.");
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (isset($tokenData->access_token)) {
|
|
362
|
+
$client = new Client();
|
|
363
|
+
$response = $client->get('https://www.googleapis.com/oauth2/v1/userinfo', [
|
|
364
|
+
'headers' => [
|
|
365
|
+
'Authorization' => 'Bearer ' . $tokenData->access_token,
|
|
366
|
+
'Accept' => 'application/json',
|
|
367
|
+
],
|
|
368
|
+
]);
|
|
369
|
+
|
|
370
|
+
if ($response->getStatusCode() == 200) {
|
|
371
|
+
$responseInfo = json_decode($response->getBody()->getContents());
|
|
372
|
+
|
|
373
|
+
$accountData = [
|
|
374
|
+
'provider' => 'google',
|
|
375
|
+
'type' => 'oauth',
|
|
376
|
+
'providerAccountId' => "$responseInfo->id",
|
|
377
|
+
'access_token' => $tokenData->access_token,
|
|
378
|
+
'expires_at' => $tokenData->expires_at ?? null,
|
|
379
|
+
'token_type' => $tokenData->token_type,
|
|
380
|
+
'scope' => $tokenData->scope,
|
|
381
|
+
];
|
|
382
|
+
|
|
383
|
+
$this->saveAuthInfo($responseInfo, $accountData);
|
|
384
|
+
|
|
385
|
+
$userToAuthenticate = [
|
|
386
|
+
'name' => $responseInfo->name,
|
|
387
|
+
'email' => $responseInfo->email,
|
|
388
|
+
'image' => $responseInfo->picture,
|
|
389
|
+
'Account' => (object)$accountData
|
|
390
|
+
];
|
|
391
|
+
$userToAuthenticate = (object)$userToAuthenticate;
|
|
392
|
+
|
|
393
|
+
$this->authenticate($userToAuthenticate, $googleProvider->maxAge);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
class GoogleProvider
|
|
400
|
+
{
|
|
401
|
+
public function __construct(
|
|
402
|
+
public string $clientId,
|
|
403
|
+
public string $clientSecret,
|
|
404
|
+
public string $redirectUri,
|
|
405
|
+
public string $maxAge = '30d'
|
|
406
|
+
) {
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
class GithubProvider
|
|
411
|
+
{
|
|
412
|
+
public function __construct(
|
|
413
|
+
public string $clientId,
|
|
414
|
+
public string $clientSecret,
|
|
415
|
+
public string $maxAge = '30d'
|
|
416
|
+
) {
|
|
417
|
+
}
|
|
184
418
|
}
|