ai added simple ui for register and login
This commit is contained in:
Generated
+10
@@ -0,0 +1,10 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Ignored default folder with query files
|
||||
/queries/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
Generated
+22
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="InertiaPackage">
|
||||
<option name="directoryPaths">
|
||||
<list />
|
||||
</option>
|
||||
</component>
|
||||
<component name="LaravelIdeaMainSettings">
|
||||
<option name="codeGeneration">
|
||||
<LaravelCodeGeneration>
|
||||
<option name="generationStringSettings">
|
||||
<map>
|
||||
<entry key="createEloquentScope:namespace" value="Models\Scopes" />
|
||||
<entry key="createModel:namespace" value="Models" />
|
||||
</map>
|
||||
</option>
|
||||
</LaravelCodeGeneration>
|
||||
</option>
|
||||
<option name="frameworkFound" value="true" />
|
||||
<option name="userClassName" value="\App\Models\User" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/php-com-cen.iml" filepath="$PROJECT_DIR$/.idea/php-com-cen.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
Generated
+29
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" packagePrefix="ComCen\" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/cboden/ratchet" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/evenement/evenement" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-factory" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/ratchet/rfc6455" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/react/cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/react/dns" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/react/event-loop" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/react/promise" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/react/socket" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/react/stream" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/deprecation-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-foundation" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php83" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/routing" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
Generated
+45
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MessDetectorOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCSFixerOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCodeSnifferOptionsConfiguration">
|
||||
<option name="highlightLevel" value="WARNING" />
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PhpIncludePathManager">
|
||||
<include_path>
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-factory" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
|
||||
<path value="$PROJECT_DIR$/vendor/react/promise" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
|
||||
<path value="$PROJECT_DIR$/vendor/react/cache" />
|
||||
<path value="$PROJECT_DIR$/vendor/react/dns" />
|
||||
<path value="$PROJECT_DIR$/vendor/react/stream" />
|
||||
<path value="$PROJECT_DIR$/vendor/react/event-loop" />
|
||||
<path value="$PROJECT_DIR$/vendor/react/socket" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php83" />
|
||||
<path value="$PROJECT_DIR$/vendor/ratchet/rfc6455" />
|
||||
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
|
||||
<path value="$PROJECT_DIR$/vendor/cboden/ratchet" />
|
||||
<path value="$PROJECT_DIR$/vendor/evenement/evenement" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
|
||||
<path value="$PROJECT_DIR$/vendor/composer" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.0">
|
||||
<option name="suggestChangeDefaultLanguageLevel" value="false" />
|
||||
</component>
|
||||
<component name="PhpStanOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PsalmOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -13,10 +13,17 @@ class LoginController implements HttpServerInterface
|
||||
public function onOpen(ConnectionInterface $conn, RequestInterface $request = null): void
|
||||
{
|
||||
$params = [];
|
||||
parse_str($request->getUri()->getQuery(), $params);
|
||||
|
||||
if (empty($params["username"]) && empty($params["password"])) {
|
||||
Utils::respondHtml($conn, $this->loginPage());
|
||||
$conn->close();
|
||||
return;
|
||||
}
|
||||
|
||||
$login = true;
|
||||
$responseHead = "";
|
||||
$json = "";
|
||||
parse_str($request->getUri()->getQuery(), $params);
|
||||
|
||||
$username = $params["username"];
|
||||
$password = $params["password"];
|
||||
@@ -49,6 +56,62 @@ class LoginController implements HttpServerInterface
|
||||
$conn->close();
|
||||
}
|
||||
|
||||
private function loginPage(): string
|
||||
{
|
||||
return <<<'HTML'
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Login — ComCen</title>
|
||||
<style>
|
||||
body { font-family: monospace; max-width: 360px; margin: 80px auto; padding: 0 16px; }
|
||||
h2 { margin-bottom: 24px; }
|
||||
input { width: 100%; box-sizing: border-box; padding: 6px; font-family: monospace; font-size: 14px; margin-bottom: 10px; border: 1px solid #ccc; }
|
||||
button { padding: 6px 16px; font-family: monospace; font-size: 14px; cursor: pointer; }
|
||||
#msg { margin-top: 12px; font-size: 13px; }
|
||||
.error { color: #c00; }
|
||||
#token-box { margin-top: 16px; display: none; }
|
||||
#token-box p { margin: 0 0 6px; }
|
||||
#token-val { width: 100%; box-sizing: border-box; padding: 6px; font-family: monospace; font-size: 12px; background: #f4f4f4; border: 1px solid #ccc; }
|
||||
a { color: inherit; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Login</h2>
|
||||
<input id="username" type="text" placeholder="Username" />
|
||||
<input id="password" type="password" placeholder="Password" />
|
||||
<button onclick="login()">Login</button>
|
||||
<div id="msg"></div>
|
||||
<div id="token-box">
|
||||
<p>Your token (paste into chat):</p>
|
||||
<input id="token-val" type="text" readonly onclick="this.select()" />
|
||||
</div>
|
||||
<p><a href="/register">No account? Register</a></p>
|
||||
<script>
|
||||
async function login() {
|
||||
const u = document.getElementById('username').value.trim();
|
||||
const p = document.getElementById('password').value.trim();
|
||||
const msg = document.getElementById('msg');
|
||||
if (!u || !p) { msg.className = 'error'; msg.textContent = 'Fill in all fields.'; return; }
|
||||
msg.textContent = '';
|
||||
const res = await fetch('/login?username=' + encodeURIComponent(u) + '&password=' + encodeURIComponent(p));
|
||||
const data = await res.json();
|
||||
if (data.token) {
|
||||
document.getElementById('token-val').value = data.token;
|
||||
document.getElementById('token-box').style.display = 'block';
|
||||
} else {
|
||||
msg.className = 'error';
|
||||
msg.textContent = data.error || 'Login failed.';
|
||||
}
|
||||
}
|
||||
document.addEventListener('keydown', e => { if (e.key === 'Enter') login(); });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
}
|
||||
|
||||
public function onMessage(ConnectionInterface $from, $msg): void {}
|
||||
public function onClose(ConnectionInterface $conn): void {}
|
||||
public function onError(ConnectionInterface $conn, \Exception $e): void { $conn->close(); }
|
||||
|
||||
@@ -12,10 +12,17 @@ class RegisterController implements HttpServerInterface
|
||||
public function onOpen(ConnectionInterface $conn, RequestInterface $request = null): void
|
||||
{
|
||||
$params = [];
|
||||
parse_str($request->getUri()->getQuery(), $params);
|
||||
|
||||
if (empty($params["username"]) && empty($params["password"])) {
|
||||
Utils::respondHtml($conn, $this->registerPage());
|
||||
$conn->close();
|
||||
return;
|
||||
}
|
||||
|
||||
$createAccount = true;
|
||||
$responseHead = "";
|
||||
$json = "";
|
||||
parse_str($request->getUri()->getQuery(), $params);
|
||||
|
||||
$username = $params["username"];
|
||||
$password = $params["password"];
|
||||
@@ -53,6 +60,57 @@ class RegisterController implements HttpServerInterface
|
||||
$conn->close();
|
||||
}
|
||||
|
||||
private function registerPage(): string
|
||||
{
|
||||
return <<<'HTML'
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Register — ComCen</title>
|
||||
<style>
|
||||
body { font-family: monospace; max-width: 360px; margin: 80px auto; padding: 0 16px; }
|
||||
h2 { margin-bottom: 24px; }
|
||||
input { width: 100%; box-sizing: border-box; padding: 6px; font-family: monospace; font-size: 14px; margin-bottom: 10px; border: 1px solid #ccc; }
|
||||
button { padding: 6px 16px; font-family: monospace; font-size: 14px; cursor: pointer; }
|
||||
#msg { margin-top: 12px; font-size: 13px; }
|
||||
.error { color: #c00; }
|
||||
.success { color: #080; }
|
||||
a { color: inherit; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Register</h2>
|
||||
<input id="username" type="text" placeholder="Username" />
|
||||
<input id="password" type="password" placeholder="Password (min 5 chars)" />
|
||||
<button onclick="register()">Register</button>
|
||||
<div id="msg"></div>
|
||||
<p><a href="/login">Already have an account? Login</a></p>
|
||||
<script>
|
||||
async function register() {
|
||||
const u = document.getElementById('username').value.trim();
|
||||
const p = document.getElementById('password').value.trim();
|
||||
const msg = document.getElementById('msg');
|
||||
if (!u || !p) { msg.className = 'error'; msg.textContent = 'Fill in all fields.'; return; }
|
||||
msg.textContent = '';
|
||||
const res = await fetch('/register?username=' + encodeURIComponent(u) + '&password=' + encodeURIComponent(p));
|
||||
const data = await res.json();
|
||||
if (data.error === 'none') {
|
||||
msg.className = 'success';
|
||||
msg.textContent = 'Account created! Redirecting to login...';
|
||||
setTimeout(() => window.location.href = '/login', 1200);
|
||||
} else {
|
||||
msg.className = 'error';
|
||||
msg.textContent = data.error || 'Registration failed.';
|
||||
}
|
||||
}
|
||||
document.addEventListener('keydown', e => { if (e.key === 'Enter') register(); });
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
HTML;
|
||||
}
|
||||
|
||||
public function onMessage(ConnectionInterface $from, $msg): void {}
|
||||
public function onClose(ConnectionInterface $conn): void {}
|
||||
public function onError(ConnectionInterface $conn, \Exception $e): void { $conn->close(); }
|
||||
|
||||
@@ -10,4 +10,9 @@ class Utils
|
||||
{
|
||||
$conn->send("HTTP/1.1 {$head}\r\nContent-Type: application/json\r\n\r\n{$jsonData}");
|
||||
}
|
||||
|
||||
static function respondHtml(ConnectionInterface $conn, string $html): void
|
||||
{
|
||||
$conn->send("HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n{$html}");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user