Skip to content

Commit

Permalink
feat: add naive auth to server requests
Browse files Browse the repository at this point in the history
  • Loading branch information
cpvalente committed Jan 14, 2025
1 parent aa929fd commit 26cc840
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 1 deletion.
1 change: 1 addition & 0 deletions apps/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"exports": "./src/index.js",
"dependencies": {
"@googleapis/sheets": "^5.0.5",
"cookie-parser": "^1.4.7",
"cors": "^2.8.5",
"dotenv": "^16.0.1",
"express": "^4.21.1",
Expand Down
40 changes: 39 additions & 1 deletion apps/server/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import cors from 'cors';
import serverTiming from 'server-timing';

// Import middleware configuration
import cookieParser from 'cookie-parser';
import { bodyParser } from './middleware/bodyParser.js';
import { compressedStatic } from './middleware/staticGZip.js';

Expand Down Expand Up @@ -81,6 +82,36 @@ app.options('*', cors());
// Implement middleware
app.use(bodyParser);
app.use(prefix, compressedStatic);
app.use(cookieParser());

// this password will need to come here from somewhere (ie: env)
const password = 'password';
const authenticatedMiddleware = (req, res, next) => {
if (!password) {
next();
}

// the token will either be in the params or in the cookie
const token = req.query.token || req.cookies?.token;
if (token === password) {
return next();
}

const redirectUrl = `${prefix}/login?redirect=${encodeURIComponent(req.originalUrl)}`;
res.redirect(`${prefix}/login?redirect=${redirectUrl}`);
};

// on the form post we check the password and set the cookie
// TODO: check that the user cookie is removed if the password changes
app.post(`${prefix}/login`, (req, res) => {
if (!password || req.body.password === password) {
res.cookie('token', password, { httpOnly: true, secure: true, sameSite: 'strict' });
res.redirect(`${prefix}${req.body.redirect}`);
return;
}

res.status(401).send('Unauthorized');
});

// Implement route endpoints
app.use(`${prefix}/data`, appRouter); // router for application data
Expand All @@ -94,7 +125,14 @@ app.use(`${prefix}/external`, (req, res) => {
});
app.use(`${prefix}/user`, express.static(publicDir.userDir));

app.get(`${prefix}/*`, (_req, res) => {
// login route serves the login static page
app.get(`${prefix}/login`, (_req, res) => {
res.sendFile(srcFiles.login);
});

// any requests to the static assets will fail
// TODO: what do we want to put behind auth? just the http api?
app.get(`${prefix}/*`, authenticatedMiddleware, (_req, res) => {
res.sendFile(srcFiles.clientIndexHtml);
});

Expand Down
80 changes: 80 additions & 0 deletions apps/server/src/html/login.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="robots" content="noindex" />
<title>Ontime Login</title>
<style>
body,
html {
font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana,
sans-serif;
background: #101010;
color: #fafafa;
text-align: center;
box-sizing: border-box;
}

h1 {
padding-top: 30vh;
font-size: 3rem;
color: #ff7597;
font-weight: 400;
}

input {
all: unset;
text-align: start;
padding-left: 0.5rem;
background-color: #fffffa;
color: black;

height: 2rem;
border-radius: 2px;
margin-right: 0.5rem;
}
input:focus {
outline: revert;
color: #262626;
}

button {
all: unset;
color: #779be7;
background: #2d2d2d;
height: 2rem;
padding-inline: 2rem;
border-radius: 2px;
cursor: pointer;
}

button:hover {
background: #404040;
}

button:focus {
outline: revert;
}
</style>
</head>

<body>
<form method="post" class="form">
<h1>Welcome to Ontime</h1>
<input type="hidden" name="redirect" value="" id="redirect" />
<input type="password" name="password" placeholder="Password" required />
<button type="submit">Login</button>
</form>
</body>
<script>
// Get the query parameters from the URL
const params = new URLSearchParams(window.location.search);
const redirect = params.get('redirect');

// Set the value of the hidden input field
if (redirect) {
document.getElementById('redirect').value = redirect;
}
</script>
</html>
32 changes: 32 additions & 0 deletions apps/server/src/middleware/authenticate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import cookieParser from 'cookie-parser';

app.use(cookieParser());

// this password will need to come here from somewhere (ie: env)
const password = 'password';
export const authenticatedMiddleware = (req, res, next) => {
if (!password) {
next();
}

// the token will either be in the params or in the cookie
const token = req.query.token || req.cookies?.token;
if (token === password) {
return next();
}

const redirectUrl = `${prefix}/login?redirect=${encodeURIComponent(req.originalUrl)}`;
res.redirect(`${prefix}/login?redirect=${redirectUrl}`);
};

// on the form post we check the password and set the cookie
// TODO: check that the user cookie is removed if the password changes
app.post(`${prefix}/login`, (req, res) => {
if (!password || req.body.password === password) {
res.cookie('token', password, { httpOnly: true, secure: true, sameSite: 'strict' });
res.redirect(`${prefix}${req.body.redirect}`);
return;
}

res.status(401).send('Unauthorized');
});
2 changes: 2 additions & 0 deletions apps/server/src/setup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ export const srcFiles = {
userReadme: join(srcDir.root, config.user, 'README.md'),
/** Path to bundled CSS readme */
cssReadme: join(srcDir.root, config.user, config.styles.directory, 'README.md'),
/** Path to login */
login: join(srcDir.root, 'html/login.html'),
};

/**
Expand Down
18 changes: 18 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 26cc840

Please sign in to comment.