commit e287822c97c5f3a3a7bcaf27a86d28f243d308b0
parent bc89555c9a6325dfafc171736b75ed1432ed20ec
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Sun, 24 Mar 2024 20:41:58 -0700
Add button to revoke session tokens in account page
Also change revoketokens() return type from sqlbox_code to int
because in this case it only matters if it succeeds or fails, not
why it fails.
Diffstat:
5 files changed, 54 insertions(+), 7 deletions(-)
diff --git a/pages/account.c b/pages/account.c
@@ -1,8 +1,13 @@
+#define const
+
#include <string.h>
#include "common.h"
#include "pages.h"
+#define DeleteAccountStr "account"
+#define DeleteAuthTokensStr "logins"
+
enum kcgi_err
pageaccount(struct pagedata *pd)
{
@@ -11,22 +16,49 @@ pageaccount(struct pagedata *pd)
"Account",
.css = css
};
+ char *k;
enum kcgi_err status;
if (!pd->user)
return errorpage(pd, KHTTP_401);
- if (pd->req.fieldmap[KeyDelete] && strcmp(pd->req.fieldmap[KeyDelete]->parsed.s, "yes") == 0) {
- if (deleteuser(pd, pd->user->hash) == 0)
- return redirect(pd, pd->pages[PageIndex], "Account deleted");
- else
- return errorpage(pd, KHTTP_500);
+ if (pd->req.fieldmap[KeyDelete]) {
+ k = pd->req.fieldmap[KeyDelete]->parsed.s;
+ if (strcmp(k, DeleteAccountStr) == 0) {
+ if (deleteuser(pd, pd->user->hash) == 0)
+ return redirect(pd, pd->pages[PageIndex], "Account deleted");
+ else
+ return errorpage(pd, KHTTP_500);
+ } else if (strcmp(k, DeleteAuthTokensStr) == 0) {
+ if (revoketokens(pd, pd->user->hash))
+ return errorpage(pd, KHTTP_500);
+ else
+ return redirect(pd, pd->pages[PageIndex], "Session revoked");
+ }
}
if ((status = tk_startpage(pd, &template, KHTTP_200)) != KCGI_OK ||
(status = htmlwithin(pd, KELEM_H1, "Account")) != KCGI_OK ||
- (status = htmlwithin(pd, KELEM_H2, "Delete account")) != KCGI_OK ||
+ (status = htmlwithin(pd, KELEM_H2, "Manage Sessions")) != KCGI_OK ||
+ /* Session Management */
+ (status = khtml_elem(&pd->html, KELEM_FORM)) != KCGI_OK ||
+ (status = khtml_elem(&pd->html, KELEM_LABEL)) != KCGI_OK ||
+ (status = khtml_puts(&pd->html, "Revoke session keys: ")) != KCGI_OK ||
+ (status = khtml_attr(&pd->html, KELEM_INPUT,
+ KATTR_TYPE, "hidden",
+ KATTR_NAME, pd->keys[KeyDelete].name,
+ KATTR_VALUE, DeleteAuthTokensStr,
+ KATTR__MAX)) != KCGI_OK ||
+ (status = khtml_closeelem(&pd->html, 1)) != KCGI_OK ||
+ (status = khtml_putc(&pd->html, ' ')) != KCGI_OK ||
+ (status = khtml_attr(&pd->html, KELEM_INPUT,
+ KATTR_TYPE, "submit",
+ KATTR_VALUE, "Revoke",
+ KATTR__MAX)) != KCGI_OK ||
+ (status = khtml_closeelem(&pd->html, 1)) != KCGI_OK ||
+ /* Account Deletion */
+ (status = htmlwithin(pd, KELEM_H2, "Delete Account")) != KCGI_OK ||
(status = htmlwithin(pd, KELEM_P, "Deleting an account is irreversible:"
" no account data can be restored after deletion.")) != KCGI_OK ||
(status = khtml_elem(&pd->html, KELEM_FORM)) != KCGI_OK ||
@@ -35,7 +67,7 @@ pageaccount(struct pagedata *pd)
(status = khtml_attr(&pd->html, KELEM_INPUT,
KATTR_TYPE, "checkbox",
KATTR_NAME, pd->keys[KeyDelete].name,
- KATTR_VALUE, "yes",
+ KATTR_VALUE, DeleteAccountStr,
KATTR_REQUIRED, "true",
KATTR__MAX)) != KCGI_OK ||
(status = khtml_closeelem(&pd->html, 1)) != KCGI_OK ||
diff --git a/stmt.c b/stmt.c
@@ -72,6 +72,9 @@ struct sqlbox_pstmt pstmts[] = {
[StmtAddAuthToken] = { .stmt =
"INSERT into authtokens VALUES (?, ?, ?, unixepoch())"
},
+ [StmtRevokeAuthTokens] = { .stmt =
+ "DELETE FROM authtokens WHERE userid IS ?"
+ },
/*
* Currently, the user can set the end time with a
diff --git a/stmt.h b/stmt.h
@@ -12,6 +12,7 @@ enum StmtID {
StmtGetUserByToken,
StmtDeleteUser,
StmtAddAuthToken,
+ StmtRevokeAuthTokens,
StmtStartTime,
StmtStartBreakTime,
StmtEndBreakTime,
diff --git a/user.c b/user.c
@@ -143,6 +143,16 @@ addtoken(struct pagedata *pd, char *hash, char *token, time_t expires)
Len(params), params, 0);
}
+int
+revoketokens(struct pagedata *pd, char *hash)
+{
+ struct sqlbox_parm param =
+ { .sparm = hash, .type = SQLBOX_PARM_STRING };
+
+ return sqlbox_exec(pd->db, pd->dbid, StmtRevokeAuthTokens, 1, ¶m, 0) !=
+ SQLBOX_CODE_OK;
+}
+
char *
newtoken(struct pagedata *pd, char *hash)
{
diff --git a/user.h b/user.h
@@ -29,3 +29,4 @@ enum user_error getuser(struct user **user, struct pagedata *pd,
char *field, char *value);
enum user_error loginuser(struct user **ruser, struct pagedata *pd,
char *name, char *key);
+int revoketokens(struct pagedata *pd, char *hash);