Merge branch 'master' of https://gitea.polaris-1.work/teknomunk/apogee
commit
33ab478771
@ -0,0 +1 @@
|
||||
Subproject commit c667899bd898056810acfe349da59491198fbb1f
|
@ -0,0 +1,191 @@
|
||||
#include "controller/admin.h"
|
||||
|
||||
// Model
|
||||
#include "src/model/server.h"
|
||||
#include "src/model/owner.h"
|
||||
#include "src/model/account.h"
|
||||
#include "src/model/crypto/keys.h"
|
||||
|
||||
// View
|
||||
|
||||
// Controller
|
||||
#include "src/controller/api/client_apps.h"
|
||||
|
||||
// Submodules
|
||||
#include "form.h"
|
||||
#include "format.h"
|
||||
#include "http/server/request.h"
|
||||
#include "ffdb/fs_list.h"
|
||||
|
||||
// Platform Headers
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
const char* view_checkbox( bool value )
|
||||
{
|
||||
return value ? "checked" : "";
|
||||
}
|
||||
|
||||
bool route_admin_request( struct http_request* req )
|
||||
{
|
||||
// TODO: authenticate
|
||||
if( !check_authentication_header(req) ) {
|
||||
printf( "User-Agent: %s\n", http_request_get_header(req,"user-agent") );
|
||||
|
||||
http_request_send_headers( req, 401, "text/plain", true );
|
||||
FILE* f = http_request_get_response_body( req );
|
||||
fprintf( f, "Not authorized to use this endpoint.\n" );
|
||||
return true;
|
||||
}
|
||||
|
||||
if( http_request_route_term( req, "/server-setup" ) ) {
|
||||
return handle_admin_server_setup(req);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Special: /, step=1
|
||||
bool handle_admin_initial_owner_setup( struct http_request* req )
|
||||
{
|
||||
if( http_request_route_method( req, "POST" ) ) {
|
||||
// TODO: handle post
|
||||
FILE* body = http_request_get_request_data(req);
|
||||
struct form_parser* fp = form_pull_parser_new(body);
|
||||
if( !fp ) { goto show_owner_setup; }
|
||||
|
||||
struct owner* o = owner_new();
|
||||
|
||||
// Create owner account
|
||||
struct account* owner = account_new();
|
||||
owner->id = owner_account_id;
|
||||
owner->server = strdup(g_server->domain);
|
||||
owner->account_url = aformat("https://%s/owner/actor", g_server->domain );
|
||||
owner->banner = aformat("https://%s/owner/banner.blob", g_server->domain );
|
||||
owner->avatar.url = aformat("https://%s/owner/avatar.blob", g_server->domain );
|
||||
owner->avatar.static_url = aformat("https://%s/owner/avatar.blob", g_server->domain );
|
||||
owner->note = strdup("");
|
||||
account_save(owner);
|
||||
|
||||
// Create home timeline account
|
||||
{
|
||||
struct account* home = account_new();
|
||||
home->id = home_timeline_id;
|
||||
home->handle = strdup("%home-timeline");
|
||||
home->server = strdup("localhost");
|
||||
account_save(home);
|
||||
account_free(home);
|
||||
}
|
||||
|
||||
// Create public timeline account
|
||||
{
|
||||
struct account* public = account_new();
|
||||
public->id = public_timeline_id;
|
||||
public->handle = strdup("%public-timeline");
|
||||
public->server = strdup("localhost");
|
||||
account_save(public);
|
||||
account_free(public);
|
||||
}
|
||||
|
||||
fs_list_set( "data/accounts/HEAD", 3 );
|
||||
|
||||
// Create RSA public/private keys
|
||||
struct crypto_keys* keys = crypto_keys_new();
|
||||
crypt_keys_generate(keys);
|
||||
crypto_keys_save_public(keys,"data/owner/public.pem");
|
||||
crypto_keys_save_private(keys,"data/owner/private.pem");
|
||||
crypto_keys_free(keys);
|
||||
|
||||
bool success = false;
|
||||
char* password = NULL;
|
||||
char* confirm = NULL;
|
||||
|
||||
char* key = NULL;
|
||||
while( (key=form_pull_parser_read_key(fp)) ) {
|
||||
if( 0 == strcmp(key,"password") ) {
|
||||
password = strdup(form_pull_parser_read_value(fp));
|
||||
} else if( 0 == strcmp(key,"confirm") ) {
|
||||
confirm = strdup(form_pull_parser_read_value(fp));
|
||||
} else if( 0 == strcmp(key,"handle") ) {
|
||||
owner->handle = strdup(form_pull_parser_read_value(fp));
|
||||
owner->display_name = strdup(owner->handle);
|
||||
account_save(owner);
|
||||
}
|
||||
}
|
||||
|
||||
if( owner->handle && *owner->handle && password && confirm && ( 0 == strcmp(password,confirm) ) ) {
|
||||
owner_set_password( o, password );
|
||||
success = true;
|
||||
}
|
||||
form_pull_parser_release(fp);
|
||||
|
||||
if( success ) {
|
||||
owner_save(o);
|
||||
}
|
||||
owner_free(o);
|
||||
account_free(owner);
|
||||
|
||||
if( success ) {
|
||||
// TODO: generate crypto keys
|
||||
|
||||
// Advance wizard to next step
|
||||
g_server->configured = true;
|
||||
app_args_save();
|
||||
|
||||
http_request_begin_send_headers( req, 302, false );
|
||||
http_request_send_header( req, "Location", "/?complete" );
|
||||
http_request_end_send_headers( req, false );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
show_owner_setup:
|
||||
http_request_send_headers( req, 200, "text/html", true );
|
||||
FILE* f = http_request_get_response_body( req );
|
||||
#include "view/admin/owner-setup.html.inc"
|
||||
return true;
|
||||
}
|
||||
|
||||
// Route: /admin/server-setup
|
||||
// Special: /, step=0 (when server hasn't been configured)
|
||||
bool handle_admin_server_setup( struct http_request* req )
|
||||
{
|
||||
if( http_request_route_method( req, "POST" ) ) {
|
||||
// TODO: handle post
|
||||
FILE* body = http_request_get_request_data(req);
|
||||
struct form_parser* fp = form_pull_parser_new(body);
|
||||
if( !fp ) { return false; }
|
||||
|
||||
app_args_load_from_form( g_server, fp );
|
||||
form_pull_parser_release(fp);
|
||||
|
||||
// Advance wizard to next step
|
||||
if( g_server->setup_wizard_step == 0 ) {
|
||||
g_server->setup_wizard_step = 1;
|
||||
}
|
||||
|
||||
app_args_save();
|
||||
app_args_load();
|
||||
|
||||
// Redirect
|
||||
http_request_begin_send_headers( req, 302, false );
|
||||
http_request_send_header( req, "Location", "/?account" );
|
||||
http_request_end_send_headers( req, false );
|
||||
return true;
|
||||
} else {
|
||||
http_request_send_headers( req, 200, "text/html", true );
|
||||
FILE* f = http_request_get_response_body( req );
|
||||
#include "view/admin/server-setup.html.inc"
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool handle_admin_server_setup_wizard( struct http_request* req )
|
||||
{
|
||||
switch(g_server->setup_wizard_step) {
|
||||
case 0: return handle_admin_server_setup(req);
|
||||
case 1: return handle_admin_initial_owner_setup(req);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
struct http_request;
|
||||
|
||||
bool route_admin_request( struct http_request* req );
|
||||
bool handle_admin_server_setup( struct http_request* req );
|
||||
bool handle_admin_server_setup_wizard( struct http_request* req );
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit c57a8bb19fedfb717ac0ae498b2e121f96d3507f
|
||||
Subproject commit b4edcf9a332b0bc59b9f526889cd3059c77aaa5f
|
@ -1 +1 @@
|
||||
Subproject commit e133427bb7da0224fc365252406024c207418863
|
||||
Subproject commit 74376d45529aa0b5e845cddd00005ee2aedcc66f
|
@ -0,0 +1,34 @@
|
||||
<html>%(/*
|
||||
vim: filetype=html
|
||||
*/)
|
||||
<body>
|
||||
<h1>Welcome to Apogee</h1>
|
||||
<p>
|
||||
Apogee is a single-user Activity Pub federated server intended for self-hosting.
|
||||
</p>
|
||||
|
||||
<h2>Account Settings</h2>
|
||||
<form method="POST">
|
||||
<table width='100%%'>
|
||||
<tr>
|
||||
<td width="15%%"><b>Username:</b></td>
|
||||
<td><input name="handle" type="text" /></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Password:</b></td>
|
||||
<td><input name="password" type="password" /></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Confirm Password:</b></td>
|
||||
<td><input name="confirm" type="password" /></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br/>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,77 @@
|
||||
<html>%(/*
|
||||
vim: filetype=html
|
||||
*/)
|
||||
<body>
|
||||
<h1>Welcome to Apogee</h1>
|
||||
<p>
|
||||
Apogee is a single-user Activity Pub federated server intended for self-hosting.
|
||||
</p>
|
||||
|
||||
<h2>Server Settings</h2>
|
||||
<form method="POST">
|
||||
<h3>HTTP</h3>
|
||||
<table width='100%%'>
|
||||
<tr>
|
||||
<td width="15%%"><b>ICANN Domain Name:</b></td>
|
||||
<td><input name="icann_domain" type="text" value="%s{ g_server->icann_domain ? g_server->icann_domain : "" }"/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Listen Address:</b></td>
|
||||
<td><input name="address" type="text" value="%s{ g_server->http_settings.bind_address ? g_server->http_settings.bind_address : "0.0.0.0" }"/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Listen Port:</b></td>
|
||||
<td><input name="port" type="text" value="%d{ g_server->http_settings.bind_port }" /></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>User Agent:</b></td>
|
||||
<td><input name="useragent" type="text" value="%s{ g_server->user_agent }" /></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Tor</h3>
|
||||
<table width='100%%'>
|
||||
<tr>
|
||||
<td width="15%%"><b>Disable:<b></td>
|
||||
<td><input name="disable_tor" type="checkbox" %s{ view_checkbox(g_server->disable_tor) }/></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>SOCKS Port:<b></td>
|
||||
<td><input name="socks_port" type="text" value="%d{ g_server->tor_socks_port }" /></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Other</h3>
|
||||
<table width='100%%'>
|
||||
<tr>
|
||||
<td width="15%%"><b>Outbox Discard Limit:</b></td>
|
||||
<td><input name="outbox_discard_limit" type="text" value="%d{ g_server->outbox_discard_limit }" /></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Debug Mode:</b></td>
|
||||
<td><input name="debug" type="checkbox" %s{ view_checkbox(g_server->debug) }/></td>
|
||||
<td>Greatly increases server verbosity</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Developer Mode:</b></td>
|
||||
<td><input name="develop" type="checkbox" %s{ view_checkbox(g_server->develop) }/></td>
|
||||
<td>Change server behavior to suit developers</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><b>Server Disabled:</b></td>
|
||||
<td><input name="disabled" type="checkbox" %s{ view_checkbox( g_server->disabled ) }/></td>
|
||||
<td>Turn the entire server off</td>
|
||||
</tr>
|
||||
</table>
|
||||
<br/>
|
||||
<input type="submit" />
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,33 @@
|
||||
{
|
||||
"logo":"/instance/images/logo.png",
|
||||
"brandColor": "#0482d8",
|
||||
"promoPanel":{
|
||||
"items":[
|
||||
{
|
||||
"icon": "area-chart",
|
||||
"text": "Site stats",
|
||||
"url": "https://fediverse.network/%s{ g_server->domain }"
|
||||
},
|
||||
{
|
||||
"icon": "admin",
|
||||
"text": "Server Settings",
|
||||
"url": "/admin/server-settings"
|
||||
}
|
||||
]
|
||||
},
|
||||
"defaultSettings": {
|
||||
"autoPlayGif": false,
|
||||
"themeMode": "light"
|
||||
},
|
||||
"copyright": "♡2020. Copying is an act of love. Please copy and share.",
|
||||
"navlinks": {
|
||||
"homeFooter":[
|
||||
{ "title": "About", "url": "/about" },
|
||||
{ "title": "Terms of Service", "url": "/about/tos" },
|
||||
{ "title": "Privacy Policy", "url": "/about/privacy" },
|
||||
{ "title": "DMCA", "url": "/about/dmca" },
|
||||
{ "title": "Source Code", "url": "/about#opensource" }
|
||||
]
|
||||
},
|
||||
"allowedEmoji": ["🤔", "😂", "😭", "😡", "🥰", "👍🏼", "👎🏼", "🔥", "😩", "🍆"]
|
||||
}
|
Loading…
Reference in new issue