-//
// Admin functions
//
// Copyright (c) 1996-2022 by the citadel.org team
Method URL Function
------ ------------------------------ -------------------------------------
-GET /ctdl/a/landing.html Site root redirects to here
+GET / Site root will redirect to a landing page
GET /ctdl/r/ returns a JSON-encoded list of accessible rooms
OPTIONS /ctdl/r/ROOMNAME/ returns just what you'd expect
PROPFIND /ctdl/r/ROOMNAME/ Show a bunch of crap
GET /ctdl/r/ROOMNAME/ Returns information about the room (name, view, etc.) in JSON format
GET /ctdl/r/ROOMNAME/msgs.all JSON array of message list in room
GET /ctdl/r/ROOMNAME/msgs.new JSON array of message list in room (new messages)
-GET /ctdl/r/ROOMNAME/MSGNUM Retrieve the content of an individual message (FIXME: make msg headers HTTP headers)
+GET /ctdl/r/ROOMNAME/MSGNUM Retrieve the content of an individual message
+ (Should we output RFC822 fields as HTTP headers? Decide soon...)
PUT /ctdl/r/ROOMNAME/xxx DAV operation to insert a new message into a room
(The returned ETag will be the new message number)
GET /ctdl/r/ROOMNAME/MSGNUM/json Retrieve an individual message in a room, encapsulated in JSON
POST /ctdl/a/login Send it a your credentials and it will log you in
GET /ctdl/a/whoami
GET /ctdl/u/USERNAME/userpic Returns an image containing the photo/avatar of the specified user
+GET /ctdl/s/ Static content (html, css, js, images...)
+GET /.well-known/ Static content (RFC5785 compliant paths)
-//
// Functions that handle communication with a Citadel Server
//
// Copyright (c) 1987-2022 by the citadel.org team
int len = 0;
int c = 0;
- if (buf == NULL)
+ if (buf == NULL) {
return (-1);
+ }
while (len < maxbytes) {
c = read(ctdl->sock, &buf[len], 1);
// Read lines of text from the Citadel server until a 000 terminator is received.
// Implemented in terms of ctdl_readline() and is therefore transparent...
// Returns a newly allocated StrBuf or NULL for error.
-StrBuf *ctdl_readtextmsg(struct ctdlsession * ctdl) {
+StrBuf *ctdl_readtextmsg(struct ctdlsession *ctdl) {
char buf[1024];
StrBuf *sj = NewStrBuf();
if (!sj) {
// Write to the Citadel server. For now we're just wrapping write() in case we
// need to add anything else later.
-ssize_t ctdl_write(struct ctdlsession * ctdl, const void *buf, size_t count) {
+ssize_t ctdl_write(struct ctdlsession *ctdl, const void *buf, size_t count) {
return write(ctdl->sock, buf, count);
}
// Extract from the headers, the username and password the client is attempting to use.
// This could be HTTP AUTH or it could be in the cookies.
void extract_auth(struct http_transaction *h, char *authbuf, int authbuflen) {
- if (authbuf == NULL)
+ if (authbuf == NULL) {
return;
- authbuf[0] = 0;
+ }
+
+ memset(authbuf, 0, authbuflen);
char *authheader = header_val(h, "Authorization");
if (authheader) {
if (!strncasecmp(authheader, "Basic ", 6)) {
safestrncpy(authbuf, &authheader[6], authbuflen);
- return; // HTTP-AUTH was found -- stop here
+ return; // HTTP-AUTH was found -- stop here
}
}
if (strlen(authbuf) < 3) { // impossibly small
authbuf[0] = 0;
}
- return; // Cookie auth was found -- stop here
+ return; // Cookie auth was found -- stop here
}
}
// no authorization found in headers ... this is an anonymous session
// Lock the connection pool while we claim our connection
pthread_mutex_lock(&cpool_mutex);
- if (cpool != NULL)
+ if (cpool != NULL) {
for (cptr = cpool; ((cptr != NULL) && (my_session == NULL)); cptr = cptr->next) {
if ((cptr->is_bound == 0) && (!strcmp(cptr->auth, auth))) {
my_session = cptr;
my_session->is_bound = 1;
}
}
+ }
if (my_session == NULL) {
syslog(LOG_DEBUG, "No qualifying sessions , starting a new one");
my_session = malloc(sizeof(struct ctdlsession));
if (my_session->sock < 3) {
is_new_session = 1;
}
- else { // make sure our Citadel session is still good
+ else { // make sure our Citadel session is still good
int test_conn;
test_conn = ctdl_write(my_session, HKEY("NOOP\n"));
if (test_conn < 5) {
// GNU General Public License for more details.
+// This is where the login screen (modal) is displayed.
+// It appears in the "ctdl_big_modal" div which is defined in index.html and is used for several different modals.
+// If you want to change the look of the login dialog, this is where to change it.
function display_login_screen(any_message) {
-
document.getElementById("ctdl_big_modal").innerHTML =
"<div class=\"w3-modal-content\">"
- + " <div class=\"w3-panel w3-border w3-border-blue w3-topbar w3-bottombar w3-leftbar w3-rightbar\"><center>"
-
- + "<p>Put the login screen here, dummy</p>"
+ + "<div class=\"w3-panel w3-border w3-border-blue w3-topbar w3-bottombar w3-leftbar w3-rightbar\"><center>"
+ + "<p>FIXME put a login banner here, dummy</p>"
+ "<p>" + any_message + "</p>"
+ "<table border=0><tr><td>"
+ _("User name:") + "</td><td><input type=\"text\" id=\"username\"></td></tr><tr><td>"
+ "<p>"
+ "<button class=\"w3-button w3-blue\" onClick=\"javascript:login_button()\">" + _("Log in") + "</button>"
+ "</p>"
-
- + " </center></div>"
+ + "</center></div>"
+ "</div>";
document.getElementById("ctdl_big_modal").style.display = "block";
}
+// When the user elects to log out, we just call /ctdl/a/logout and let the system flush the session.
+// When we go back to ctdl_startup() it will detect that we are no longer logged in, and do the right thing.
function logout() {
- var request = new XMLHttpRequest();
- request.open("GET", "/ctdl/a/logout", true);
- request.onreadystatechange = function() {
- login_result(this.responseText);
- };
- request.send();
- request = null;
+ response = await fetch("/ctdl/a/logout");
+ ctdl_startup();
}