big change

This commit is contained in:
florian 2025-09-05 22:47:10 +02:00
parent eeb6dffcf2
commit fdbea29b82
13 changed files with 635 additions and 402 deletions

1
.gitignore vendored
View File

@ -1,4 +1,3 @@
node_modules node_modules
package-lock.json
db/database.db db/database.db
.env .env

View File

@ -32,25 +32,19 @@ function sendMail(to, subject, html) {
.catch(error => console.error('Error sending email:', error)); .catch(error => console.error('Error sending email:', error));
} }
// Middleware for checking the token function authenticateToken(req, res, next) {
const verifyToken = (req, res, next) => { const authHeader = req.headers['authorization'];
// Get the token from the headers const token = authHeader && authHeader.split(' ')[1];
const token = req.headers.authorization?.replace("Bearer ", ""); if (!token) return res.sendStatus(401);
jwt.verify(token, process.env.JWT_SECRET, (err, user) => {
if (err) return res.sendStatus(403);
req.user = user;
next();
});
}
// Check if the token is missing
if (!token) {
return res.status(403).json({ error: "Acces unauthorized, token required" });
}
try {
// Decode the token and set the user information in the request
req.user = jwt.verify(token, jwtSecret);
// The token is valid and the user is authorized to access the route
next();
} catch (error) {
return res.status(401).json({ error: "Acces unauthorized, invalid token" });
}
};
const db = await open({ const db = await open({
filename: './db/database.db', filename: './db/database.db',
@ -103,6 +97,11 @@ app.get('/', (req, res) => {
} }
); );
// Exemple d'utilisation:
app.get('/api/loginToken', authenticateToken, (req, res) => {
res.json({ message: 'Accès autorisé', user: req.user });
});
app.post('/api/login', async (req, res) => { app.post('/api/login', async (req, res) => {
const { username, password } = req.body; const { username, password } = req.body;
@ -117,20 +116,24 @@ app.post('/api/login', async (req, res) => {
return res.status(401).json({ message: 'Invalid username or password' }); return res.status(401).json({ message: 'Invalid username or password' });
} }
// Check password (replace with real password check logic)
const isPasswordValid = bcrypt.compareSync(password, user.password); const isPasswordValid = bcrypt.compareSync(password, user.password);
if (!isPasswordValid) { if (!isPasswordValid) {
return res.status(401).json({ message: 'Invalid username or password' }); return res.status(401).json({ message: 'Invalid username or password' });
} }
res.status(200).json({ message: 'Login successful' }); // Générer le token JWT
const token = jwt.sign(
{ id: user.id, username: user.username, email: user.email, historyToDefault: user.historyToDefault, admin: user.admin },
process.env.JWT_SECRET, // à définir dans ton .env
{ expiresIn: process.env.JWT_EXPIRATION }
);
res.status(200).json({ message: 'Login successful', token });
} catch (err) { } catch (err) {
console.error('Database error:', err); console.error('Database error:', err);
res.status(500).json({ message: 'Internal server error' }); res.status(500).json({ message: 'Internal server error' });
} }
} });
);
app.post('/api/register', async (req, res) => { app.post('/api/register', async (req, res) => {
const { username, email, password } = req.body; const { username, email, password } = req.body;
@ -225,5 +228,4 @@ app.post('/api/verify', async (req, res) => {
app.listen(port, "127.0.0.1", () => { app.listen(port, "127.0.0.1", () => {
console.log(`Server is running on localhost:${port}`); console.log(`Server is running on localhost:${port}`);
} }
); );

43
otherPages/index.html Normal file
View File

@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PengLogin</title>
<link rel="stylesheet" href="styles/common.css">
<link rel="stylesheet" href="styles/index.css">
<link rel="icon" href="imgs/favicon.ico" type="image/x-icon">
<script src="scripts/common.js" defer></script>
<script src="scripts/index.js" defer></script>
</head>
<body id="body" class="body">
<header id="header" class="blur">
</header>
<main>
<div class="card blur" id="login-card">
<h2>LOGIN</h2>
<form id="login-form" class="form">
<label for="username or email">Username or email:</label>
<input type="text" id="username" name="username" required>
<label for="password">Password:</label>
<input type="password" id="password" name="password" required>
<button type="submit">Login</button>
</form>
<a href="/register">Create account.</a>
</div>
<div class="card blur hidden" id="login-success">
<h2>Login successful!</h2>
</div>
</main>
<footer id="footer" class="blur">
</footer>
</body>
</html>

503
package-lock.json generated Normal file
View File

@ -0,0 +1,503 @@
{
"name": "penglogin",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "penglogin",
"version": "1.0.0",
"license": "ISC",
"dependencies": {
"dotenv": "^16.5.0",
"jsonwebtoken": "^9.0.2",
"nodemailer": "^7.0.3",
"nodemon": "^3.1.10"
}
},
"node_modules/anymatch": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
"license": "ISC",
"dependencies": {
"normalize-path": "^3.0.0",
"picomatch": "^2.0.4"
},
"engines": {
"node": ">= 8"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"license": "MIT"
},
"node_modules/binary-extensions": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
"license": "MIT",
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/brace-expansion": {
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"node_modules/braces": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/buffer-equal-constant-time": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
"license": "BSD-3-Clause"
},
"node_modules/chokidar": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
"license": "MIT",
"dependencies": {
"anymatch": "~3.1.2",
"braces": "~3.0.2",
"glob-parent": "~5.1.2",
"is-binary-path": "~2.1.0",
"is-glob": "~4.0.1",
"normalize-path": "~3.0.0",
"readdirp": "~3.6.0"
},
"engines": {
"node": ">= 8.10.0"
},
"funding": {
"url": "https://paulmillr.com/funding/"
},
"optionalDependencies": {
"fsevents": "~2.3.2"
}
},
"node_modules/concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"license": "MIT"
},
"node_modules/debug": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/dotenv": {
"version": "16.5.0",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz",
"integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://dotenvx.com"
}
},
"node_modules/ecdsa-sig-formatter": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
"license": "Apache-2.0",
"dependencies": {
"safe-buffer": "^5.0.1"
}
},
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/fsevents": {
"version": "2.3.3",
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"hasInstallScript": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
"node_modules/glob-parent": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"license": "MIT",
"engines": {
"node": ">=4"
}
},
"node_modules/ignore-by-default": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
"integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
"license": "ISC"
},
"node_modules/is-binary-path": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
"license": "MIT",
"dependencies": {
"binary-extensions": "^2.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/is-extglob": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-glob": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/is-number": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"license": "MIT",
"engines": {
"node": ">=0.12.0"
}
},
"node_modules/jsonwebtoken": {
"version": "9.0.2",
"resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
"integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
"license": "MIT",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
"lodash.isboolean": "^3.0.3",
"lodash.isinteger": "^4.0.4",
"lodash.isnumber": "^3.0.3",
"lodash.isplainobject": "^4.0.6",
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
"semver": "^7.5.4"
},
"engines": {
"node": ">=12",
"npm": ">=6"
}
},
"node_modules/jwa": {
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.2.tgz",
"integrity": "sha512-eeH5JO+21J78qMvTIDdBXidBd6nG2kZjg5Ohz/1fpa28Z4CcsWUzJ1ZZyFq/3z3N17aZy+ZuBoHljASbL1WfOw==",
"license": "MIT",
"dependencies": {
"buffer-equal-constant-time": "^1.0.1",
"ecdsa-sig-formatter": "1.0.11",
"safe-buffer": "^5.0.1"
}
},
"node_modules/jws": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
"integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
"license": "MIT",
"dependencies": {
"jwa": "^1.4.1",
"safe-buffer": "^5.0.1"
}
},
"node_modules/lodash.includes": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
"integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==",
"license": "MIT"
},
"node_modules/lodash.isboolean": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
"integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==",
"license": "MIT"
},
"node_modules/lodash.isinteger": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
"integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==",
"license": "MIT"
},
"node_modules/lodash.isnumber": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
"integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==",
"license": "MIT"
},
"node_modules/lodash.isplainobject": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
"integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
"license": "MIT"
},
"node_modules/lodash.isstring": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
"integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
"license": "MIT"
},
"node_modules/lodash.once": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
"license": "MIT"
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
"license": "ISC",
"dependencies": {
"brace-expansion": "^1.1.7"
},
"engines": {
"node": "*"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/nodemailer": {
"version": "7.0.3",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.3.tgz",
"integrity": "sha512-Ajq6Sz1x7cIK3pN6KesGTah+1gnwMnx5gKl3piQlQQE/PwyJ4Mbc8is2psWYxK3RJTVeqsDaCv8ZzXLCDHMTZw==",
"license": "MIT-0",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/nodemon": {
"version": "3.1.10",
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.10.tgz",
"integrity": "sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==",
"license": "MIT",
"dependencies": {
"chokidar": "^3.5.2",
"debug": "^4",
"ignore-by-default": "^1.0.1",
"minimatch": "^3.1.2",
"pstree.remy": "^1.1.8",
"semver": "^7.5.3",
"simple-update-notifier": "^2.0.0",
"supports-color": "^5.5.0",
"touch": "^3.1.0",
"undefsafe": "^2.0.5"
},
"bin": {
"nodemon": "bin/nodemon.js"
},
"engines": {
"node": ">=10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/nodemon"
}
},
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
"license": "MIT",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"license": "MIT",
"engines": {
"node": ">=8.6"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/pstree.remy": {
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
"integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
"license": "MIT"
},
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
"license": "MIT",
"dependencies": {
"picomatch": "^2.2.1"
},
"engines": {
"node": ">=8.10.0"
}
},
"node_modules/safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/semver": {
"version": "7.7.2",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz",
"integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/simple-update-notifier": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
"integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
"license": "MIT",
"dependencies": {
"semver": "^7.5.3"
},
"engines": {
"node": ">=10"
}
},
"node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"license": "MIT",
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/to-regex-range": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
},
"engines": {
"node": ">=8.0"
}
},
"node_modules/touch": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
"integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
"license": "ISC",
"bin": {
"nodetouch": "bin/nodetouch.js"
}
},
"node_modules/undefsafe": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
"integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
"license": "MIT"
}
}
}

View File

@ -1,2 +0,0 @@
<p>&copy; 2025 The land of the penguin</p>
<p>Contact us at: <a href="mailto:florian@thepenguninontheweb.tech">florian@thepenguinontheweb.tech</a></p>

View File

@ -1,13 +0,0 @@
<a href="https://thepenguinontheweb.tech/index.html" class="header-link">
The land of the penguin
</a>
<div class="back-button"">
<svg width=" 24" height="8" viewBox="0 0 16 8" fill="none" class="arrow-icon">
<path d="M15 4H4V1" stroke="#C99CCF" />
<path d="M14.5 4H3.5H0" stroke="#C99CCF" />
<path
d="M15.8536 4.35355C16.0488 4.15829 16.0488 3.84171 15.8536 3.64645L12.6716 0.464466C12.4763 0.269204 12.1597 0.269204 11.9645 0.464466C11.7692 0.659728 11.7692 0.976311 11.9645 1.17157L14.7929 4L11.9645 6.82843C11.7692 7.02369 11.7692 7.34027 11.9645 7.53553C12.1597 7.7308 12.4763 7.7308 12.6716 7.53553L15.8536 4.35355ZM15 4.5L15.5 4.5L15.5 3.5L15 3.5L15 4.5Z"
fill="#C99CCF" />
</svg>
</div>

View File

@ -5,11 +5,13 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PengLogin</title> <title>PengLogin</title>
<link rel="stylesheet" href="styles/common.css"> <link rel="stylesheet" href="https://commonhtml.thepenguinontheweb.tech/styles/common.css">
<!-- <link rel="stylesheet" href="http://localhost:4999/styles/common.css" /> -->
<link rel="stylesheet" href="styles/index.css"> <link rel="stylesheet" href="styles/index.css">
<link rel="icon" href="imgs/favicon.ico" type="image/x-icon"> <link rel="icon" href="imgs/favicon.ico" type="image/x-icon">
<script src="scripts/common.js" defer></script> <script src="https://commonhtml.thepenguinontheweb.tech/scripts/common.js" defer></script>
<script src="scripts/index.js" defer></script> <script src="scripts/index.js" defer></script>
<script src="scripts/common.js" defer></script>
</head> </head>
<body id="body" class="body"> <body id="body" class="body">
@ -17,7 +19,7 @@
</header> </header>
<main> <main>
<div class="card blur"> <div class="card blur" id="login-card">
<h2>LOGIN</h2> <h2>LOGIN</h2>
<form id="login-form" class="form"> <form id="login-form" class="form">
<label for="username or email">Username or email:</label> <label for="username or email">Username or email:</label>
@ -26,11 +28,14 @@
<label for="password">Password:</label> <label for="password">Password:</label>
<input type="password" id="password" name="password" required> <input type="password" id="password" name="password" required>
<button type="submit">Login</button> <button class="button" type="submit">Login</button>
</form> </form>
<a href="/register">Create account.</a> <a href="/register">Create account.</a>
</div> </div>
<div class="card blur hidden" id="login-success">
<h2>Login successful!</h2>
</div>
</main> </main>
<footer id="footer" class="blur"> <footer id="footer" class="blur">

View File

@ -5,11 +5,13 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PengRegister</title> <title>PengRegister</title>
<link rel="stylesheet" href="styles/common.css"> <link rel="stylesheet" href="https://commonhtml.thepenguinontheweb.tech/styles/common.css">
<!-- <link rel="stylesheet" href="http://localhost:4999/styles/common.css" /> -->
<link rel="stylesheet" href="styles/register.css"> <link rel="stylesheet" href="styles/register.css">
<link rel="icon" href="imgs/favicon.ico" type="image/x-icon"> <link rel="icon" href="imgs/favicon.ico" type="image/x-icon">
<script src="scripts/common.js" defer></script> <script src="https://commonhtml.thepenguinontheweb.tech/scripts/common.js" defer></script>
<script src="scripts/register.js" defer></script> <script src="scripts/register.js" defer></script>
<script src="scripts/common.js" defer></script>
</head> </head>
<body id="body" class="body"> <body id="body" class="body">
@ -32,7 +34,7 @@
<label for="confirm-password">Confirm Password:</label> <label for="confirm-password">Confirm Password:</label>
<input type="password" id="confirm-password" name="confirmPassword" required> <input type="password" id="confirm-password" name="confirmPassword" required>
<button type="submit">Register</button> <button type="submit" class="button">Register</button>
</form> </form>
<a href="/login">Login Page.</a> <a href="/login">Login Page.</a>

View File

@ -1,20 +1 @@
const headerElement = document.querySelector('header');
const footerElement = document.querySelector('footer');
async function loadHeaderFooter() {
try {
const headerResponse = await fetch('/header-snippet.html');
if (!headerResponse.ok) throw new Error('Failed to load header');
const headerHTML = await headerResponse.text();
headerElement.innerHTML = headerHTML;
const footerResponse = await fetch('/footer-snippet.html');
if (!footerResponse.ok) throw new Error('Failed to load footer');
const footerHTML = await footerResponse.text();
footerElement.innerHTML = footerHTML;
} catch (error) {
console.error('Error loading header/footer:', error);
}
}
loadHeaderFooter(); loadHeaderFooter();

View File

@ -1,4 +1,6 @@
const loginForm = document.getElementById('login-form'); const loginForm = document.getElementById('login-form');
const loginCard = document.getElementById('login-card');
const loginSuccess = document.getElementById('login-success');
loginForm.addEventListener('submit', async (event) => { loginForm.addEventListener('submit', async (event) => {
event.preventDefault(); event.preventDefault();
@ -16,7 +18,13 @@ loginForm.addEventListener('submit', async (event) => {
}); });
if (response.ok) { if (response.ok) {
alert('Login successful!'); const responseData = await response.json();
console.log('Login successful:', responseData);
localStorage.setItem('token', responseData.token);
displayLoginSuccess();
} else { } else {
const errorData = await response.json(); const errorData = await response.json();
alert(`Login failed: ${errorData.message}`); alert(`Login failed: ${errorData.message}`);
@ -26,4 +34,37 @@ loginForm.addEventListener('submit', async (event) => {
alert('An error occurred while trying to log in.'); alert('An error occurred while trying to log in.');
} }
} }
); );
async function isLoggedInFunction() {
const token = localStorage.getItem('token');
if (!token) return false;
try {
const response = await fetch('/api/loginToken', {
method: 'GET',
headers: {
'Authorization': `Bearer ${token}`
}
});
if (response.ok) {
return true;
} else {
localStorage.removeItem('token');
return false;
}
} catch (error) {
console.error('Error checking login status:', error);
return false;
}
}
function displayLoginSuccess() {
loginCard.classList.add('hidden');
loginSuccess.classList.remove('hidden');
}
isLoggedInFunction().then((logged) => {
if (logged) displayLoginSuccess();
});

View File

@ -1,331 +0,0 @@
html,
body {
height: 100%;
width: 100%;
/* Fait en sorte que html et body prennent toute la hauteur */
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
/* Affichage en colonne */
align-items: center;
justify-content: space-between;
/* Centre le contenu verticalement et horizontalement */
min-height: 100vh;
/* S'assure que le body prend au minimum toute la hauteur de la vue */
a {
text-decoration: none;
/* Enlève le soulignement des liens */
color: inherit;
/* Hérite de la couleur du parent */
}
}
.body {
background: repeating-conic-gradient(from 45deg,
#a37fb1 0% 25%,
#604566 0% 50%);
background-size: max(10vw, 10svh) max(10vw, 10svh);
display: flex;
/* Transforme le body en conteneur flex */
flex-direction: column;
/* Affichage en colonne */
min-height: 100vh;
/* S'assure que le body prend au minimum toute la hauteur de la vue */
animation: background 0.5s ease-in-out;
/* Animation de transition pour le fond */
}
header {
font-size: 20px;
height: 90px;
min-height: 90px;
width: calc(100% - 80px);
color: #C99CCF;
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
flex-direction: row;
background: #433147d8;
margin: 20px;
border-radius: 10px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-ms-border-radius: 10px;
-o-border-radius: 10px;
}
.blur::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
/* Pour Safari */
z-index: -1;
/* Assure que le fond est derrière le contenu */
}
.blur {
position: relative;
/* Nécessaire pour le positionnement du pseudo-élément */
}
footer {
font-size: 20px;
height: 90px;
min-height: 90px;
width: calc(100% - 80px);
color: rgb(201, 156, 207);
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 20px;
flex-direction: row;
background: #433147d8;
margin: 20px;
border-radius: 10px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-ms-border-radius: 10px;
-o-border-radius: 10px;
font-size: 0.875rem;
p {
width: 100%;
text-align: center;
}
}
main {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: auto;
}
.card-container {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 100%;
height: auto;
gap: 20px;
/* Espace entre les cartes */
}
@media (max-width: 768px) {
.card-container {
flex-direction: column;
}
}
.card {
border-radius: 10px;
padding: 20px;
min-width: 300px;
width: auto;
min-height: 400px;
height: auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 10px;
text-decoration: none;
color: rgb(201, 156, 207);
background: #433147d8;
transition: background 0.3s ease-in-out, transform 0.3s ease-in-out, margin 0.3s ease-in-out;
cursor: pointer;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5);
}
.card:hover {
transform: scale(1.05);
transition: background 0.3s ease-in-out, transform 0.3s ease-in-out, margin 0.3s ease-in-out;
margin: 7px;
}
.card::before {
border-radius: 10px;
}
.card-image {
height: 200px;
width: 200px;
border-radius: 10px;
}
.presentation {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: auto;
width: 1000px;
cursor: default;
gap: 30px;
/* Espace entre les éléments de la carte */
h1 {
color: white;
}
}
.info.card {
min-width: 500px;
width: auto;
height: auto;
cursor: default;
h2 {
font-size: 20px;
color: rgb(255, 255, 255);
text-align: center;
}
p {
font-size: 16px;
text-align: center;
}
.card-container {
display: grid;
grid-template-columns: repeat(5, 1fr);
/* 2 colonnes de largeur égale */
gap: 20px;
width: 1400px;
.card {
cursor: default;
h3 {
font-size: 18px;
color: rgb(255, 255, 255);
text-align: center;
}
background-color: #FFFFFF00;
width: calc(100% - 40px);
/* Les cartes prennent toute la largeur de la colonne */
height: 180px;
/* Hauteur automatique pour s'adapter au contenu */
}
}
}
.form {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 100%;
height: auto;
gap: 20px;
/* Espace entre les éléments du formulaire */
label {
width: 90%;
}
input,
textarea {
width: 90%;
max-width: 500px;
/* Largeur maximale pour les champs de saisie */
padding: 10px;
border-radius: 5px;
border: none;
background-color: #C99CCF30;
color: white;
font-size: 16px;
margin-bottom: 10px;
/* Espace entre les champs */
}
button {
padding: 10px 20px;
border-radius: 5px;
border: none;
background-color: #C99CCF;
color: white;
font-size: 16px;
cursor: pointer;
transition: background-color 0.3s ease-in-out;
&:hover {
background-color: #A37FB1;
/* Couleur au survol */
}
}
}
.arrow-icon {
width: 50px;
height: auto;
cursor: pointer;
path:nth-child(2) {
d: path('M14.5 4H3.5H4');
}
path {
transition: 0.25s ease;
}
&:hover {
path:nth-child(1) {
d: path('M15 4H4V4');
}
path:nth-child(2) {
d: path('M14.5 4H3.5H0');
transform: translateX(4px);
}
path:nth-child(3) {
transform: translateX(4px);
}
}
}
.hidden {
display: none;
/* Cache l'élément */
}

0
public/styles/verify.css Normal file
View File

View File

@ -5,10 +5,13 @@
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PengRegister</title> <title>PengRegister</title>
<link rel="stylesheet" href="styles/common.css"> <link rel="stylesheet" href="https://commonhtml.thepenguinontheweb.tech/styles/common.css">
<!-- <link rel="stylesheet" href="http://localhost:4999/styles/common.css" /> -->
<link rel="stylesheet" href="styles/verify.css">
<link rel="icon" href="imgs/favicon.ico" type="image/x-icon"> <link rel="icon" href="imgs/favicon.ico" type="image/x-icon">
<script src="scripts/common.js" defer></script> <script src="https://commonhtml.thepenguinontheweb.tech/scripts/common.js" defer></script>
<script src="scripts/verify.js" defer></script> <script src="scripts/verify.js" defer></script>
<script src="scripts/common.js" defer></script>
</head> </head>
<body id="body" class="body"> <body id="body" class="body">
@ -19,7 +22,7 @@
<div class="card blur" id="verify-card"> <div class="card blur" id="verify-card">
<h2>Verify account</h2> <h2>Verify account</h2>
<p>To verify your account, please enter the verification code sent to your email.</p> <p>To verify your account, please enter the verification code sent to your email.</p>
<button id="verify-button">Verify</button> <button id="verify-button" class="button">Verify</button>
<a href="/register">Register Page.</a> <a href="/register">Register Page.</a>
</div> </div>