added login

This commit is contained in:
didier amyot committed 2023-12-11 11:59:30 -05:00
1 parent 171657d616
commit 0cb2d25a62
3 files changed
+137 -26

No files matched your search

+59 -24
View File
@@ -8,10 +8,16 @@ import {QuestionSource, QuestionMeta} from './shared.ts';
type Question = [QuestionSource, QuestionMeta];
type QuestionURLS = {
nextQuestionUrl: string,
validationUrl: string,
answerQuestionUrl: string
};
const questions: Question = Object.values(rawQuestions).flatMap(s => s.questions.map( q => [s, q]));
const router = new Router();
const apiRouter = new Router();
const loginRouter = new Router();
const app = new Application();
function hashString(str: string): number {
@@ -45,7 +51,7 @@ function getRandomQuestion<T>(seed: string, index: number, questions: Question[
}
function getQuestionPage(question: Question, nextQuestionUrl: string, validationUrl: string, answerQuestionUrl: string){
function getQuestionPage(question: Question, urls: QuestionURLS){
return (<div>
<pre> { question[0].toString() }</pre>
<div class="content mt-2 mb-2">
@@ -64,15 +70,15 @@ function getQuestionPage(question: Question, nextQuestionUrl: string, validation
<button class="button is-info"
hx-trigger="click"
hx-target="#message"
hx-post={validationUrl} >
hx-post={urls.validationUrl} >
Verify Answer
</button>
</div>
<div class="control">
<a class="button is-info"
href="#"
hx-trigger="next-question from:body delay:1500ms, click"
hx-get={nextQuestionUrl}
hx-trigger="next-question from:body delay:500ms, click"
hx-get={urls.nextQuestionUrl}
hx-params="none"
hx-target="#question-body" >
Next Question
@@ -83,7 +89,7 @@ function getQuestionPage(question: Question, nextQuestionUrl: string, validation
<a class="button is-info"
href="#"
hx-trigger="click"
hx-get={answerQuestionUrl}
hx-get={urls.answerQuestionUrl}
hx-params="none"
hx-target="#message" >
Show Answer
@@ -120,43 +126,72 @@ function processValidAnswer(ctx, answer: string): void {
}
router.all("/api/v1/random-questions/:seed/:idx/validate", async (ctx)=> {
function getQuestion(ctx): Question{
const seed = ctx.params.seed;
const index = Number.parseInt(ctx.params.idx??"0");
return getRandomQuestion(seed, index, questions);
}
function getUrls(ctx): QuestionURLS{
const seed = ctx.params.seed;
const index = Number.parseInt(ctx.params.idx??"0");
const answer = (await ctx.request.body().value).get("answer");
const nextQuestionUrl = `/api/v1/random-questions/${seed}/${index + 1}`;
const q = getRandomQuestion(seed, index, questions);
const validationUrl = `/api/v1/random-questions/${seed}/${index}/validate`;
const answerQuestionUrl = `/api/v1/random-questions/${seed}/${index}/answer`
return {nextQuestionUrl, validationUrl, answerQuestionUrl};
}
apiRouter.post("/api/v1/random-questions/:seed/:idx/validate", async (ctx)=> {
const answer = (await ctx.request.body().value).get("answer");
const q = getQuestion(ctx);
if(isValidAnswer(q, answer)){
processValidAnswer(ctx, nextQuestionUrl)
processValidAnswer(ctx, getUrls(ctx).nextQuestionUrl)
}else{
processInvalidAnswer(ctx, nextQuestionUrl)
processInvalidAnswer(ctx, getUrls(ctx).nextQuestionUrl)
}
})
router.get("/api/v1/random-questions/:seed/:idx/answer", (ctx)=> {
const seed = ctx.params.seed;
const index = Number.parseInt(ctx.params.idx??"0");
const q = getRandomQuestion(seed, index, questions);
apiRouter.get("/api/v1/random-questions/:seed/:idx/answer", (ctx)=> {
const q = getQuestion(ctx);
ctx.response.body = renderToString(
<div class="notification is-warning">
The answer is {q[1].answer}
</div>);
})
router.get("/api/v1/random-questions/:seed/:idx", (ctx)=> {
const seed = ctx.params.seed;
const index = Number.parseInt(ctx.params.idx??"0");
const q = getRandomQuestion(seed, index, questions);
const nextQuestionUrl = `/api/v1/random-questions/${seed}/${index + 1}`;
const validationUrl = `/api/v1/random-questions/${seed}/${index}/validate`;
const answerQuestionUrl = `/api/v1/random-questions/${seed}/${index}/answer`
apiRouter.get("/api/v1/random-questions/:seed/:idx", (ctx)=> {
const q = getQuestion(ctx);
const urls = getUrls(ctx);
ctx.response.body = renderToString(getQuestionPage(q, nextQuestionUrl, validationUrl, answerQuestionUrl));
ctx.response.body = renderToString(getQuestionPage(q, urls));
ctx.response.headers.append("HX-Trigger", JSON.stringify({'set-question-id': ctx.params.idx}));
});
app.use(router.routes());
loginRouter.post("/api/v1/login", async (ctx)=> {
const username = (await ctx.request.body().value).get("username");
ctx.response.headers.append("HX-Trigger", JSON.stringify({'set-seed': username}));
ctx.response.body = username;
});
loginRouter.post("/api/v1/logout", (ctx)=> {
ctx.response.headers.append("HX-Trigger", "logout");
ctx.response.body = "";
});
app.use(loginRouter.routes());
app.use(staticFiles("public", {brotli: true, fetch: true}));
app.use(async (ctx, next) => {
if(!ctx.request.headers.get('session')){
console.log("user not logged in.")
ctx.response.headers.append("HX-Redirect", "/login.html");
return
}
await next();
})
app.use(apiRouter.routes());
await app.listen({ port: 8000 });