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
|
public function onOpen(ConnectionInterface $conn, RequestInterface $request = null): void
|
||||||
{
|
{
|
||||||
$params = [];
|
$params = [];
|
||||||
|
parse_str($request->getUri()->getQuery(), $params);
|
||||||
|
|
||||||
|
if (empty($params["username"]) && empty($params["password"])) {
|
||||||
|
Utils::respondHtml($conn, $this->loginPage());
|
||||||
|
$conn->close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$login = true;
|
$login = true;
|
||||||
$responseHead = "";
|
$responseHead = "";
|
||||||
$json = "";
|
$json = "";
|
||||||
parse_str($request->getUri()->getQuery(), $params);
|
|
||||||
|
|
||||||
$username = $params["username"];
|
$username = $params["username"];
|
||||||
$password = $params["password"];
|
$password = $params["password"];
|
||||||
@@ -49,6 +56,62 @@ class LoginController implements HttpServerInterface
|
|||||||
$conn->close();
|
$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 onMessage(ConnectionInterface $from, $msg): void {}
|
||||||
public function onClose(ConnectionInterface $conn): void {}
|
public function onClose(ConnectionInterface $conn): void {}
|
||||||
public function onError(ConnectionInterface $conn, \Exception $e): void { $conn->close(); }
|
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
|
public function onOpen(ConnectionInterface $conn, RequestInterface $request = null): void
|
||||||
{
|
{
|
||||||
$params = [];
|
$params = [];
|
||||||
|
parse_str($request->getUri()->getQuery(), $params);
|
||||||
|
|
||||||
|
if (empty($params["username"]) && empty($params["password"])) {
|
||||||
|
Utils::respondHtml($conn, $this->registerPage());
|
||||||
|
$conn->close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
$createAccount = true;
|
$createAccount = true;
|
||||||
$responseHead = "";
|
$responseHead = "";
|
||||||
$json = "";
|
$json = "";
|
||||||
parse_str($request->getUri()->getQuery(), $params);
|
|
||||||
|
|
||||||
$username = $params["username"];
|
$username = $params["username"];
|
||||||
$password = $params["password"];
|
$password = $params["password"];
|
||||||
@@ -53,6 +60,57 @@ class RegisterController implements HttpServerInterface
|
|||||||
$conn->close();
|
$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 onMessage(ConnectionInterface $from, $msg): void {}
|
||||||
public function onClose(ConnectionInterface $conn): void {}
|
public function onClose(ConnectionInterface $conn): void {}
|
||||||
public function onError(ConnectionInterface $conn, \Exception $e): void { $conn->close(); }
|
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}");
|
$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