aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiquel Lionel <lionel@les-miquelots.net>2021-07-25 12:30:41 +0100
committerMiquel Lionel <lionelmiquel@sfr.fr>2021-08-23 15:44:44 +0100
commitf32ba587cbca216c5d65583bc2cf4d41e6987e33 (patch)
tree8c4d7b1a59a288d5a86bae3622882611505ea545
parent5785614b247f64647d48e2980c2bbec8e2cdbc4b (diff)
downloadgpigeon-f32ba587cbca216c5d65583bc2cf4d41e6987e33.tar.gz
gpigeon-f32ba587cbca216c5d65583bc2cf4d41e6987e33.zip
added account creation by invite links
- Fix some wordings in gpigeonctl - add the ability to list users in gpigeonctl - fix input name for file upload: its not 'file' but 'fupload' - update styles.css for invite web interface - add INVITE_TEMPLATE_PATH variable to config.dek.mk - Improved some function error messages in gpigeon template
-rw-r--r--Makefile162
-rw-r--r--config.def.mk1
-rwxr-xr-xgpigeon-template.cgi233
-rwxr-xr-xgpigeonctl.def.pl163
-rwxr-xr-xinvites-tmpl-template.cgi282
-rw-r--r--link-tmpl-template.cgi2
-rw-r--r--styles.css310
7 files changed, 806 insertions, 347 deletions
diff --git a/Makefile b/Makefile
index 323e708..92c561c 100644
--- a/Makefile
+++ b/Makefile
@@ -2,11 +2,57 @@
BOLD=\033[01m
RED=\033[31m
+UDRL=\033[4m
STOP=\033[0m
include config.mk
-gpigeon: gpigeon-template.cgi link-tmpl-template.cgi
- $(MAKE) gpigeonctl;
+gpigeon: gpigeon-template.cgi link-tmpl-template.cgi invites-tmpl-template.cgi
+ @if test -z '$(PREFIX)'; then \
+ printf "\n$(RED)No $(BOLD)\u0024PREFIX$(STOP)$(RED) variable defined in config.mk.\n";\
+ printf "Look into config.def.mk for the defaults and fix that in your config.mk.$(STOP)\n";\
+ exit 1;\
+ else \
+ printf "\n$(UDRL)\u0024PREFIX$(STOP) var is set to $(BOLD)$(PREFIX)$(STOP)";\
+ fi
+ @if test -z '$(BINPREFIX)'; then \
+ printf "\n$(RED)No $(BOLD)\u0024BINPREFIX$(STOP)$(RED) variable defined in config.mk.\n";\
+ printf "Look into config.def.mk for the defaults and fix that in your config.mk.$(STOP)\n";\
+ exit 1;\
+ else \
+ printf "\n$(UDRL)\u0024BINPREFIX$(STOP) var is set to $(BOLD)$(BINPREFIX)$(STOP)";\
+ fi
+ @if test -z '$(WWWPREFIX)'; then\
+ printf "\n${RED}No web directory defined in config.mk. Check your config.def.mk for the defaults and fix that in your config.mk.${STOP}";\
+ exit 1; \
+ else \
+ printf "\nThe WWW directory is $(BOLD)$(WWWDIR)$(STOP)";\
+ fi
+ @if test -n '$(COOKIES_DIR)'; then \
+ printf "\nThe cookies will be stored in ${BOLD}$(COOKIES_DIR)${STOP}"; \
+ else \
+ printf "\n${RED}No cookie directory configured. Check your config.def.mk for the defaults and fix that.${STOP}" ;\
+ exit 1; \
+ fi
+ @if test -n '$(_GPG_HOMEDIR)'; then \
+ printf "\nThe home directory for GPG will be ${BOLD}$(_GPG_HOMEDIR)${STOP}" ;\
+ else \
+ printf "\n${RED}The GPG home directory for gpigeon wasn't set in config.mk . Fix that.${STOP}" ;\
+ $(MAKE) clean ;\
+ exit 1;\
+ fi
+ @if test -n '$(TEST_GPG_HOMEDIR)'; then \
+ printf "\nThe home directory for GPG tests will be ${BOLD}$(TEST_GPG_HOMEDIR)${STOP}" ;\
+ else \
+ printf "\n${RED}The GPG tests home directory for gpigeon wasn't set in config.mk . Fix that.${STOP}" ;\
+ $(MAKE) clean ;\
+ exit 1;\
+ fi
+ @if test -z '$(DB_PATH)'; then\
+ printf "\n${RED}No database path defined in config.mk. Check your config.def.mk for the defaults and fix that in your config.mk$(STOP)";\
+ exit 1; \
+ else \
+ printf "\nThe path to the SQLite database is $(BOLD)$(DB_PATH)$(STOP)";\
+ fi
@if test -n '$(LINK_TEMPLATE_PATH)'; then \
printf "\nLink template is at ${BOLD}$(LINK_TEMPLATE_PATH)${STOP}\n"; \
@@ -20,7 +66,26 @@ gpigeon: gpigeon-template.cgi link-tmpl-template.cgi
printf "\n${RED}The temporary directory for uploaded files wasn't set in your config.mk. Fix that.${STOP}" ;\
exit 1;\
fi
-
+ @if test -n '$(WWWUSER)'; then \
+ printf "\nThe following UNIX user will be used for chowning and gpigeonctl: ${BOLD}$(WWWUSER)${STOP}\n"; \
+ else \
+ printf "\t${RED}No user configured. Check your config.mk${STOP}.\n"; \
+ $(MAKE) clean ; \
+ exit 1; \
+ fi
+ @if test -n '$(WWWGROUP)'; then \
+ printf "The following UNIX group will be used for chowning: ${BOLD}$(WWWGROUP)${STOP}\n"; \
+ else \
+ printf "\t${RED}No group configured. Check your config.mk${STOP}.\n"; \
+ $(MAKE) clean ; \
+ exit 1; \
+ fi
+ @sed -e 's|gpgdir_goes_here|$(_GPG_HOMEDIR)|g' gpigeonctl.def.pl > gpigeonctl;
+ @sed -e 's|cookies_dir_goes_here|$(COOKIES_DIR)|g' -i gpigeonctl ;
+ @sed -e 's|db_path_goes_here|$(DB_PATH)|g' -i gpigeonctl;
+ @sed -e 's|web_user_goes_here|$(WWWUSER)|g' -i gpigeonctl;
+ @sed -e 's|web_dir_goes_here|$(WWWDIR)|g' -i gpigeonctl;
+ @sed -e 's|bin_path_goes_here|$(BINPREFIX)|g' -i gpigeonctl;
@if test -n '$(MSG_FORM_CHAR_LIMIT)'; then \
printf "\nMessage form will have a message limit of ${BOLD}$(MSG_FORM_CHAR_LIMIT) characters${STOP}\n"; \
else \
@@ -37,13 +102,16 @@ gpigeon: gpigeon-template.cgi link-tmpl-template.cgi
fi
@sed -e 's|bin_path_goes_here|$(BINPREFIX)|g' gpigeon-template.cgi > gpigeon.cgi;
@sed -e 's|db_path_goes_here|$(DB_PATH)|g' -i gpigeon.cgi;
+ @sed -e 's|db_path_goes_here|$(DB_PATH)|g' invites-tmpl-template.cgi > invites-tmpl.cgi;
@sed -e 's|link_template_path_goes_here|$(LINK_TEMPLATE_PATH)|g' -i gpigeon.cgi;
@sed -e 's|cookies_dir_goes_here|$(COOKIES_DIR)|g' -i gpigeon.cgi;
@sed -e 's|bin_path_goes_here|$(BINPREFIX)|g' link-tmpl-template.cgi > link-tmpl.cgi;
+ @sed -e 's|bin_path_goes_here|$(BINPREFIX)|g' -i invites-tmpl.cgi;
@sed -e "s|msg_char_limit_goes_here|$(MSG_FORM_CHAR_LIMIT)|g" -i link-tmpl.cgi;
- @sed -e 's|has_mailserver_goes_here|$(HAS_MAILSERVER)|g' -i link-tmpl.cgi;
- @sed -e 's|sender_addr_goes_here|$(MAILSENDER)|g' -i link-tmpl.cgi;
- @sed -e 's|gpg_homedir_goes_here|$(_GPG_HOMEDIR)|g' -i link-tmpl.cgi;
+ @sed -e 's|has_mailserver_goes_here|$(HAS_MAILSERVER)|g' -i link-tmpl.cgi invites-tmpl.cgi;
+ @sed -e 's|sender_addr_goes_here|$(MAILSENDER)|g' -i link-tmpl.cgi invites-tmpl.cgi;
+ @sed -e 's|gpg_homedir_goes_here|$(_GPG_HOMEDIR)|g' -i link-tmpl.cgi invites-tmpl.cgi;
+ @sed -e 's|test_gpgdir_goes_here|$(TEST_GPG_HOMEDIR)|g' -i link-tmpl.cgi invites-tmpl.cgi;
@sed -e 's|tmp_dir_goes_here|$(UPLOAD_TMPDIR)|g' -i link-tmpl.cgi; \
@if [ '${HAS_MAILSERVER}' == '1' ]; then \
@@ -52,7 +120,7 @@ gpigeon: gpigeon-template.cgi link-tmpl-template.cgi
printf "External mail server setup. ${BOLD}Net::SMTPS module will be used to send the mails${STOP}.\n"; \
if test -n '$(MAILSENDER_PW)'; then \
printf "\tPassword for ${BOLD}${MAILSENDER}${STOP} is %s.\n" '${MAILSENDER_PW}'; \
- sed -e 's|sender_pw_goes_here|$(MAILSENDER_PW)|g' -i link-tmpl.cgi; \
+ sed -e 's|sender_pw_goes_here|$(MAILSENDER_PW)|g' -i link-tmpl.cgi invites-tmpl.cgi; \
else\
printf "\t${RED}Password for the sender address wasn't set in your config.mk. Fix this${STOP}.\n";\
$(MAKE) clean ; \
@@ -60,7 +128,7 @@ gpigeon: gpigeon-template.cgi link-tmpl-template.cgi
fi; \
if test -n '$(SMTP_DOMAIN)'; then \
printf "\tSMTP server: ${BOLD}$(SMTP_DOMAIN)${STOP}\n"; \
- sed -e 's|smtp_domain_goes_here|$(SMTP_DOMAIN)|g' -i link-tmpl.cgi; \
+ sed -e 's|smtp_domain_goes_here|$(SMTP_DOMAIN)|g' -i link-tmpl.cgi invites-tmpl.cgi; \
else\
printf "\t${RED}No SMTP server was configured in your config.mk. Fix this.${STOP}\n";\
$(MAKE) clean ; \
@@ -68,7 +136,7 @@ gpigeon: gpigeon-template.cgi link-tmpl-template.cgi
fi; \
if test -n '$(SMTP_PORT)'; then \
printf "\tSMTP port: ${BOLD}$(SMTP_PORT)${STOP}\n"; \
- sed -e 's|smtp_port_goes_here|$(SMTP_PORT)|g' -i link-tmpl.cgi; \
+ sed -e 's|smtp_port_goes_here|$(SMTP_PORT)|g' -i link-tmpl.cgi invites-tmpl.cgi; \
else \
printf "\t${RED}No SMTP port configured in your config.mk. Fix this${STOP}.\n"; \
$(MAKE) clean ; \
@@ -80,37 +148,12 @@ gpigeon: gpigeon-template.cgi link-tmpl-template.cgi
printf "Done generating $(WWWDOMAIN).conf for nginx.";\
fi
- @printf "\nDone preparing files. You can now type\n\t$$ sudo make install\nin your terminal.\n"
+ @printf "\nDone preparing files. You can now type\n\t$$ sudo make install\nin your terminal.\n\n"
gpigeonctl: gpigeonctl.def.pl
- @$(MAKE) check_cookiesdir;
- @$(MAKE) check_dbpath;
- @$(MAKE) check_prefixes;
- @$(MAKE) check_gpghomedir;
- @if test -n '$(WWWUSER)'; then \
- printf "The following UNIX user will be used for chowning and gpigeonctl: ${BOLD}$(WWWUSER)${STOP}\n"; \
- else \
- printf "\t${RED}No user configured. Check your config.mk${STOP}.\n"; \
- $(MAKE) clean ; \
- exit 1; \
- fi
- @if test -n '$(WWWGROUP)'; then \
- printf "The following UNIX group will be used for chowning: ${BOLD}$(WWWGROUP)${STOP}\n"; \
- else \
- printf "\t${RED}No group configured. Check your config.mk${STOP}.\n"; \
- $(MAKE) clean ; \
- exit 1; \
- fi
- @sed -e 's|gpgdir_goes_here|$(_GPG_HOMEDIR)|g' gpigeonctl.def.pl > gpigeonctl;
- @sed -e 's|cookies_dir_goes_here|$(COOKIES_DIR)|g' -i gpigeonctl ;
- @sed -e 's|db_path_goes_here|$(DB_PATH)|g' -i gpigeonctl;
- @sed -e 's|web_user_goes_here|$(WWWUSER)|g' -i gpigeonctl;
- @sed -e 's|web_dir_goes_here|$(WWWDIR)|g' -i gpigeonctl;
- @sed -e 's|bin_path_goes_here|$(BINPREFIX)|g' -i gpigeonctl;
- @chmod +x gpigeonctl;
install:
- $(MAKE) gpigeon gpigeonctl;
+ $(MAKE) gpigeon;
@if test -n "$(WWWDOMAIN)"; then\
$(MAKE) nginxconf;\
printf "\nInstalling $(WWWDOMAIN).conf into $(NGINXCONFDIR)\n";\
@@ -138,51 +181,4 @@ uninstall:
clean:
rm -f genpass.txt gpg.txt link-tmpl.cgi gpigeon.cgi $(WWWDOMAIN).conf the.db gpigeonctl
-check_cookiesdir:
- @if test -n '$(COOKIES_DIR)'; then \
- printf "\nThe cookies will be stored in ${BOLD}$(COOKIES_DIR)${STOP}"; \
- else \
- printf "\n${RED}No cookie directory configured. Check your config.def.mk for the defaults and fix that.${STOP}" ;\
- exit 1; \
- fi
-
-check_dbpath:
- @if test -z '$(DB_PATH)'; then\
- printf "\n${RED}No database path defined in config.mk. Check your config.def.mk for the defaults and fix that in your config.mk$(STOP)";\
- exit 1; \
- else \
- printf "\nThe path to the SQLite database is $(BOLD)$(DB_PATH)$(STOP)";\
- fi
-
-check_prefixes:
- @if test -z '$(PREFIX)'; then \
- printf "\n$(RED)No \u0024PREFIX variable defined in config.mk.\n";\
- printf "Look into config.def.mk for the defaults and fix that in your config.mk.$(STOP)\n";\
- exit 1;\
- else \
- printf "\n\u0024PREFIX var is set to $(BOLD)$(PREFIX)$(STOP)";\
- fi
- @if test -z '$(BINPREFIX)'; then \
- printf "\n$(RED)No \u0024BINPREFIX variable defined in config.mk.\n";\
- printf "Look into config.def.mk for the defaults and fix that in your config.mk.$(STOP)\n";\
- exit 1;\
- else \
- printf "\n\u0024BINPREFIX var is set to $(BOLD)$(BINPREFIX)$(STOP)";\
- fi
- @if test -z '$(WWWPREFIX)'; then\
- printf "\n${RED}No web directory defined in config.mk. Check your config.def.mk for the defaults and fix that in your config.mk.${STOP}";\
- exit 1; \
- else \
- printf "\nThe WWW directory is $(BOLD)$(WWWDIR)$(STOP)";\
- fi
-
-check_gpghomedir:
- @if test -n '$(_GPG_HOMEDIR)'; then \
- printf "\nThe home directory for GPG will be ${BOLD}$(_GPG_HOMEDIR)${STOP}" ;\
- else \
- printf "\n${RED}The GPG home directory for gpigeon wasn't set in config.mk . Fix that.${STOP}" ;\
- $(MAKE) clean ;\
- exit 1;\
- fi
-
.PHONY: clean install uninstall
diff --git a/config.def.mk b/config.def.mk
index f860bf3..15ec910 100644
--- a/config.def.mk
+++ b/config.def.mk
@@ -14,6 +14,7 @@ GPIGEON_DIR=$(PREFIX)/gpigeon
COOKIES_DIR = $(GPIGEON_DIR)/cookies
UPLOAD_TMPDIR = $(GPIGEON_DIR)/tmp/
LINK_TEMPLATE_PATH = $(GPIGEON_DIR)/link-tmpl.cgi
+INVITE_TEMPLATE_PATH = $(GPIGEON_DIR)/invites-tmpl.cgi
DB_PATH=$(GPIGEON_DIR)/the.db
_GPG_HOMEDIR = $(GPIGEON_DIR)/gnupg
GPIGEON_PATH = $(WWWDIR)/cgi-bin/gpigeon.cgi
diff --git a/gpigeon-template.cgi b/gpigeon-template.cgi
index 0e6b9c0..69df82a 100755
--- a/gpigeon-template.cgi
+++ b/gpigeon-template.cgi
@@ -32,6 +32,40 @@ delete @ENV{qw(IFS PATH CDPATH BASH_ENV)};
$ENV{'PATH'} = q{bin_path_goes_here};
my $rIP = $ENV{REMOTE_ADDR};
my $uagent = $ENV{HTTP_USER_AGENT};
+my %text_strings = (
+ addr => 'Address',
+ addr_ok => 'is valid!',
+ addr_nok => 'is not valid !',
+ addr_unknown => 'Unknown',
+ create_link_btn => 'Generate link',
+ cookie_problems =>'You got a cookie problem.<br> <b>Clean them and log in again</b>',
+ delete_link_btn_text => 'Delete',
+ delete_links_btn_text => 'Delete all links',
+ disconnect_btn_text => 'Disconnect',
+ here => 'here',
+ landingpage_title => 'GPIGEON - Log in',
+ logout_btn_text => 'Logout',
+ loginbtn => 'Log in',
+ link_asker_field_label => "Asker's mail :",
+ link_del_ok => 'Successful removal !',
+ link_legend_textarea =>'Type your message below :',
+ link_ok_for => 'Generated a link for',
+ link_del_failed => 'Deletion failed and here is why : ',
+ link_generated_ok => "Here's the link",
+ mailto_body => 'Your link is ',
+ mailto_subject => 'Link to your one time GPG messaging form',
+ incorrect_ids => 'Username/password combination<br> is incorrect.<br>Try again.',
+ password_label => 'Password',
+ refresh_btn => 'Refresh',
+ theader_link => 'Link',
+ theader_for => 'For',
+ theader_deletion => 'Deletion',
+ theader_cdate => 'Created on',
+ username_label => 'Username',
+ web_title => 'GPIGEON.CGI - Main',
+ web_greet_msg => 'Hi and welcome. What will you do today ?',
+);
+
sub DbGetLine {
my ($dbh, $query) = @_;
@@ -48,6 +82,54 @@ sub DbGetLine {
}
}
+sub GetFileTable {
+ my ($dir ,$hidden_loginfield) = @_;
+ my @table = ();
+ opendir my $dir_hnd, "$dir" or die "[GetFileTable function] Can't open $dir: $!";
+ while (readdir $dir_hnd) {
+ if ($_ ne '.' and $_ ne '..'){
+ my $linkfile_fn = $_;
+ my $linkstats= stat("$dir/$linkfile_fn");
+ my $mtime = scalar localtime $linkstats->mtime;
+ my $link_asker = undef;
+ if (open my $f_hnd , '<', "$dir/$linkfile_fn"){
+ for (1..2){
+ $link_asker = readline $f_hnd;
+ $link_asker =~ s/q\{(.*?)\}//i;
+ $link_asker = $1;
+ }
+ close $linkfile_handle;
+ my $for_field_body = qq{<a href="mailto:$link_asker?subject=$text_strings{mailto_subject}&body=$text_strings{mailto_body} http://$ENV{SERVER_NAME}/cgi-bin/$dir/$linkfile_fn">$link_asker</a>};
+
+ if (not defined $link_asker){
+ $for_field_body = $text_strings{addr_unknown};
+ }
+ #create links table html
+ push @table,
+ qq{<tr>
+ <td><a title="This link has been created on $mtime" href="/cgi-bin/$dir/$linkfile_fn" target="_blank" rel="noopener noreferrer nofollow">ici</a></td>
+ <td>$for_field_body</td>
+ <td>
+ <form method="POST">
+ $hidden_loginfield
+ <input type="hidden" name="adminpan" value="1">
+ <input type="hidden" name="supprlien" value="$dir/$linkfile_fn">
+ <input id="deletelinkbtn" type="submit" value="$text_strings{delete_link_btn_text}">
+ </form>
+ </td>
+ </tr>};
+
+ }
+ else {
+ close $linkfile_handle;
+ die "[GetFileTable function] Error: Can't open $linkfile_fn: $!";
+ }
+ }
+ }
+ closedir $dir_hnd;
+ return @table;
+}
+
sub LoginOk {
my ($dbh, $username, $pass, $userid, $magic_cookie, $uid_cookie, $cookiesdir) = @_;
my $loginsuccess = PasswdLogin($dbh, $username, $pass);
@@ -78,7 +160,7 @@ sub CookieLogin {
my $login_cookiefile = "$cookiesdir/$userid/$filename.txt";
if (-e $login_cookiefile){
- open my $in, '<', $login_cookiefile or die "can't read file: $!";
+ open my $in, '<', $login_cookiefile or die "[CookieLogin function] can't read file: $!";
$rip_line = readline $in;
$ua_line = readline $in;
$id_line = readline $in;
@@ -133,32 +215,6 @@ sub PasswdLogin {
return;
}
return $userid; # as an userid is always > 0, we can use it as return value
- } else {
- return;
- }
- } else {
- $dbh->disconnect;
- return;
- }
- $dbh->disconnect;
- return;
-}
-
-sub LoginCookieGen {
- my ($userid, $magic_cookie, $cookiesdir) = @_;
- if (not defined $magic_cookie){
- my $str_rand_obj = String::Random->new;
- my $val = $str_rand_obj->randregex('\w{64}');
- if (not -d "$cookiesdir/$userid"){
- mkpath("$cookiesdir/$userid");
- }
- my $cookiefile = "$cookiesdir/$userid/$val.txt";
- my $new_magic_cookie = CGI::Cookie->new(
- -name => 'id',
- -value => $val,
- -expires => '+1y',
- '-max-age' => '+1y',
- -domain => ".$ENV{'SERVER_NAME'}",
-path => '/',
-secure => 1,
-httponly => 1,
@@ -200,40 +256,7 @@ my $hostname = $ENV{'SERVER_NAME'};
my $db_path = q{db_path_goes_here};
my $cookiesdir = q{cookies_dir_goes_here};
my $link_template_path = q{link_template_path_goes_here};
-
-my %text_strings = (
- addr => 'Address',
- addr_ok => 'is valid!',
- addr_nok => 'is not valid !',
- addr_unknown => 'Unknown',
- create_link_btn => 'Generate link',
- cookie_problems =>'You got a cookie problem.<br> <b>Clean them and log in again</b>',
- delete_link_btn_text => 'Delete',
- delete_links_btn_text => 'Delete all links',
- disconnect_btn_text => 'Disconnect',
- here => 'here',
- landingpage_title => 'GPIGEON - Log in',
- logout_btn_text => 'Logout',
- loginbtn => 'Log in',
- link_asker_field_label => "Asker's mail :",
- link_del_ok => 'Successful removal !',
- link_legend_textarea =>'Type your message below :',
- link_ok_for => 'Generated a link for',
- link_del_failed => 'Deletion failed and here is why : ',
- link_generated_ok => "Here's the link",
- mailto_body => 'Your link is ',
- mailto_subject => 'Link to your one time GPG messaging form',
- incorrect_ids => 'Username/password combination<br> is incorrect.<br>Try again.',
- password_label => 'Password',
- refresh_btn => 'Refresh',
- theader_link => 'Link',
- theader_for => 'For',
- theader_deletion => 'Deletion',
- theader_cdate => 'Created on',
- username_label => 'Username',
- web_title => 'GPIGEON.CGI - Main',
- web_greet_msg => 'Hi and welcome. What will you do today ?',
-);
+my $invites_template_path = q{invite_template_goes_here};
my $cgi_query_get = CGI->new;
my $username = $cgi_query_get->param('username');
@@ -298,8 +321,7 @@ if ($disconnect and defined $magic_cookie){ # if we disconnect and cookie is act
);
my $f = "$cookiesdir/$userid/$idval.txt";
if (-e "$f"){
- unlink "$f" or die "cant delete cookie at $f :$!\n"; # delet it
-
+ unlink "$f" or die "cant delete cookie at $f :$!\n";
}
print "Set-Cookie: $delete_uid_cookie\n";
print "Set-Cookie: $delete_id_cookie\n";
@@ -315,6 +337,7 @@ if($loginok){
LoginCookieGen($userid, $magic_cookie, $cookiesdir);
my $user_mailaddr = DbGetLine($dbh, qq{SELECT mail from pigeons where userid='$userid';});
my $nick = DbGetLine($dbh, qq{SELECT name from pigeons where userid='$userid';});
+ my $gpgid = DbGetLine($dbh, qq{SELECT gpgfp from pigeons where userid='$userid';});
if (not -d "./l/$userid"){
mkpath("./l/$userid");
}
@@ -351,6 +374,7 @@ if($loginok){
while( <$in> ) {
s/{link_user}/{$link_asker}/g;
s/{user_mailaddr_goes_here}/{$user_mailaddr}/g;
+ s/{gpgid_goes_here}/{$gpgid}/g;
print $out $_;
}
close $in or die;
@@ -365,8 +389,8 @@ if($loginok){
}
- opendir my $link_dir_handle, "./l/$userid" or die "Can't open ./l: $!";
- while (readdir $link_dir_handle) {
+ opendir my $dir_hnd, "./l/$userid" or die "Can't open ./l: $!";
+ while (readdir $dir_hnd) {
if ($_ ne '.' and $_ ne '..'){
my $linkfile_fn = $_;
my $linkstats = stat("./l/$userid/$linkfile_fn");
@@ -397,7 +421,6 @@ if($loginok){
</form>
</td>
</tr>};
-
}
else {
close $linkfile_handle;
@@ -405,7 +428,7 @@ if($loginok){
}
}
}
- closedir $link_dir_handle;
+ closedir $dir_hnd;
print 'Content-type: text/html',"\n\n",
qq{<!DOCTYPE html>
<html>
@@ -464,42 +487,42 @@ else{
}
print "Content-type: text/html\n\n",
-qq{<!DOCTYPE html>
-<html lang="fr">
-<head>
-<meta charset="utf-8">
-<link rel="icon" type="image/x-icon" href="/favicon.ico">
-<link rel="stylesheet" type="text/css" href="/styles.css">
-<title>$text_strings{landingpage_title}</title>
-</head>
-<body>
-<h1>$text_strings{landingpage_title}</h1>
-<form action="/cgi-bin/gpigeon.cgi" method="POST">
-<table id="loginbox">
-<tbody>
- <tr>
- <td>$text_strings{username_label} :</td>
- <td><input type="text" name="username"></td>
- </tr>
- <tr>
- <td>$text_strings{password_label} :</td>
- <td><input type="password" name="password"></td>
- </tr>
- <tr>
- <td></td>
- <td id="loginerr">$login_notif</td>
- </tr>
- <tr id="authbtn">
- <td></td>
- <td><input type="submit" value="$text_strings{loginbtn}"></td>
- </tr>
-</tbody>
-</table>
-</form>
-
-<p><a href="http://git.les-miquelots.net/gpigeon"
- title="gpigeon download link">Source code here.</a> It is similar to <a target="_blank" rel="nofollow noopener noreferrer" href="https://hawkpost.co">hawkpost.co</a>.
-
-</body>
-</html>};
+ qq{<!DOCTYPE html>
+ <html lang="fr">
+ <head>
+ <meta charset="utf-8">
+ <link rel="icon" type="image/x-icon" href="/favicon.ico">
+ <link rel="stylesheet" type="text/css" href="/styles.css">
+ <title>$text_strings{landingpage_title}</title>
+ </head>
+ <body>
+ <h1>$text_strings{landingpage_title}</h1>
+ <form action="/cgi-bin/gpigeon.cgi" method="POST">
+ <table id="loginbox">
+ <tbody>
+ <tr>
+ <td>$text_strings{username_label} :</td>
+ <td><input type="text" name="username"></td>
+ </tr>
+ <tr>
+ <td>$text_strings{password_label} :</td>
+ <td><input type="password" name="password"></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td id="loginerr">$login_notif</td>
+ </tr>
+ <tr id="authbtn">
+ <td></td>
+ <td><input type="submit" value="$text_strings{loginbtn}"></td>
+ </tr>
+ </tbody>
+ </table>
+ </form>
+
+ <p><a href="http://git.les-miquelots.net/gpigeon"
+ title="gpigeon download link">Source code here.</a> It is similar to <a target="_blank" rel="nofollow noopener noreferrer" href="https://hawkpost.co">hawkpost.co</a>.
+
+ </body>
+ </html>};
}
diff --git a/gpigeonctl.def.pl b/gpigeonctl.def.pl
index b7d4108..86d7295 100755
--- a/gpigeonctl.def.pl
+++ b/gpigeonctl.def.pl
@@ -32,6 +32,11 @@ my $web_dir = q{web_dir_goes_here};
my ($escaddr, $ynchoice) = undef;
my $opt = $ARGV[0];
my $version = 0.1;
+my $dbh = DBI->connect("DBI:SQLite:dbname=$dbh_path", undef, undef,
+{ RaiseError => 1,
+AutoCommit => 1,
+})
+or die $DBI::errstr;
sub DbGetLine {
@@ -49,6 +54,20 @@ sub DbGetLine {
}
}
+sub ListUsers {
+ my ($dbh, $query) = @_;
+ my $prep = $dbh->prepare( $query );
+ my $exec = $prep->execute() or die $DBI::errstr;
+
+ if ($exec < 0){
+ print $DBI::errstr;
+ }
+
+ while (my @rows = $prep->fetchrow_array()) {
+ print "$row[0]\t$rows[1]";
+ }
+}
+
sub RecursiveChown {
my ($junk, $junk2, $uid, $gid) = getpwnam($web_user);
@@ -64,14 +83,14 @@ sub DeleteCookies {
}
sub EscapeArobase {
- my $esc = shift;
- if ($esc =~ /^([-\@\w.]+)$/) {
- $esc = $1; # $data now untainted
- $esc =~ s/@/\\@/;
- return $esc;
- } else {
- die "\n"; # log this somewhere
- }
+ my $esc = shift;
+ if ($esc =~ /^([-\@\w.]+)$/) {
+ $esc = $1; # $data now untainted
+ $esc =~ s/@/\\@/;
+ return $esc;
+ } else {
+ die "\n"; # log this somewhere
+ }
}
sub PrintHelp{
@@ -81,57 +100,57 @@ sub PrintHelp{
}
sub SetMail {
- print "Mail address: ";
- my $addr = <STDIN>;
- if (not Email::Valid->address($addr)){
- die "\nNot a valid email address.";
- }
+ print "Mail address: ";
+ my $addr = <STDIN>;
+ if (not Email::Valid->address($addr)){
+ die "\nNot a valid email address.";
+ }
chomp $addr;
return $addr;
}
sub SetNick {
my $addr = shift;
- print "\nNickname (optional): ";
- my $nick = <STDIN>;
- chomp $nick;
- if (length($nick) eq 0){
- $nick = $addr;
- return $nick;
- }
- elsif (defined $nick and not $nick =~ /^([\w]+)$/){
- die "\nYour nickname must have only alphanumeric characters.\n";
- }
+ print "\nNickname (optional): ";
+ my $nick = <STDIN>;
+ chomp $nick;
+ if (length($nick) eq 0){
+ $nick = $addr;
+ return $nick;
+ }
+ elsif (defined $nick and not $nick =~ /^([\w]+)$/){
+ die "\nYour nickname must have only alphanumeric characters.\n";
+ }
return $nick;
}
sub SetPasswd {
- ReadMode 2;
- print "\nPassword: ";
- my $pass = <STDIN>;
- if (not length($pass) > 10){
- ReadMode 1;
- die "\nFor your safety, you should have a password at least 10 characters long.\n";
- }
+ ReadMode 2;
+ print "\nPassword: ";
+ my $pass = <STDIN>;
+ if (not length($pass) > 10){
ReadMode 1;
- chomp $pass;
- my $salt = `openssl rand 16`;
- my $hash = argon2id_pass($pass, $salt, 3, '32M', 1, 32);
+ die "\nFor your safety, you should have a password at least 10 characters long.\n";
+ }
+ ReadMode 1;
+ chomp $pass;
+ my $salt = `openssl rand 16`;
+ my $hash = argon2id_pass($pass, $salt, 3, '32M', 1, 32);
}
sub TransferGPGPubKey {
my ($addr, $GNUPGHOME) = @_;
my $escaddr = EscapeArobase($addr);
- my $gpgid = '0x'.`gpg --with-colons -k $escaddr | grep "pub:u" | cut -d':' -f5`;
- chomp $gpgid;
- if (not $gpgid =~ /^([\w]+)$/ and not length($gpgid) eq 18){
- die "\nYour GPG 0xlong key id is not a correct one. It seems that no public key was tied to the provided e-mail address.\n";
- }
- else{
- $gpgid = $1;
- print "\nGPG ID: $gpgid\n";
- return $gpgid;
- }
+ my $gpgid = '0x'.`gpg --with-colons -k $escaddr | grep "pub:u" | cut -d':' -f5`;
+ chomp $gpgid;
+ if (not $gpgid =~ /^([\w]+)$/ and not length($gpgid) eq 18){
+ die "\nYour GPG 0xlong key id is not a correct one. It seems that no public key was tied to the provided e-mail address.\n";
+ }
+ else{
+ $gpgid = $1;
+ print "\nGPG ID: $gpgid\n";
+ return $gpgid;
+ }
}
# i should use a module for this lol
@@ -228,11 +247,6 @@ if (defined $opt){
use File::Path qw/rmtree/;
my $addr = SetMail();
my $esc = EscapeArobase($addr);
- my $dbh = DBI->connect("DBI:SQLite:dbname=$dbh_path", undef, undef,
- { RaiseError => 1,
- AutoCommit => 1,
- })
- or die $DBI::errstr;
my $uid = DbGetLine($dbh, "SELECT userid FROM pigeons WHERE mail='$esc'") or die "$!";
$dbh->do(qq{DELETE FROM pigeons where mail='$addr'}) or die $DBI::errstr;
$dbh->disconnect;
@@ -241,7 +255,7 @@ if (defined $opt){
{ verbose => 1,
safe => 1
});
- # GPG module doesn't support the delete_key yet so we yolo
+ #GPG module doesn't delete key
`GNUPGHOME="$GNUPGHOME" gpg --yes --batch --delete-key $esc`;
}
print "\nUser $addr deleted succesfully\n";
@@ -268,14 +282,63 @@ if (defined $opt){
print "All generated links have been deleted.\n";
}
exit 0;
-
}
+ if ($opt eq 'invite'){
+ my $verb = shift;
+ if ($verb eq 'gen'){
+ my $preconf_mail = undef;
+ my $mailfield = q{<input type="text" name="mailaddr" required>};
+ my $for_x = undef;
+ print "Set an email address beforehand ? [y/n] ";
+ $ynchoice = <STDIN>;
+ chomp $ynchoice;
+ if ($ynchoice eq 'o' or $ynchoice eq 'y'){
+ $preconf_mail = SetMail();
+ $mailfield = qq{<input value="$preconf_mail" type="text" name="mailaddr" required disabled>};
+ $for_x = "for $preconf_mail";
+ }
+ use File::Path qw/mkpath/;
+ mkpath($invites_dir) unless -d $invites_dir;
+ my $randengine = String::Random->new;
+ my $randfn = $randengine->randregex('\w{64}') . '.cgi';
+ my $invite_path = "$invites_dir/$randfn";
+ open my $in, '<', $invites_tmpl or die "Can't open template for invites : $!";
+ open my $out, '>', $invite_path or die "Can't write to invite path: $!";
+ while (<$in>) {
+ s/{mailfield_goes_here}/{$mailfield}/g;
+ print $out $_;
+ }
+ close $in or die "$!";
+ chmod(0755, $invite_path) or die "$!";
+ close $out or die "$!";
+ print "\nSuccess ! The link was generated to $invite_path $for_x.";
+ }
+
+ }
+
if ($opt eq 'version'){
print "$version\n";
exit 0;
}
+ if ($opt eq 'list'){
+ my $verb = shift;
+ if (defined $verb){
+ if ($verb eq 'users'){
+ my $dbh = DBI->connect("DBI:SQLite:dbname=$dbh_path", undef, undef,
+ {
+ RaiseError => 1,
+ AutoCommit => 1,
+ }) or die $DBI::errstr;
+ ListUsers($dbh);
+ }
+ }
+ else{
+ print "Valid 'list' actions are:\n\tusers\n" ;
+ }
+ }
+
PrintHelp();
}
else {
diff --git a/invites-tmpl-template.cgi b/invites-tmpl-template.cgi
new file mode 100755
index 0000000..3681546
--- /dev/null
+++ b/invites-tmpl-template.cgi
@@ -0,0 +1,282 @@
+#!/usr/bin/perl -T
+my $mail = undef;
+use warnings;
+use strict;
+use DBI;
+use CGI qw/param/;
+use CGI::Carp qw/fatalsToBrowser/;
+use Crypt::Argon2 qw/argon2id_pass/;
+use Email::Valid;
+use Net::SMTP;
+use Net::SMTPS;
+use String::Random;
+use File::Path qw/make_path rmtree/;
+use Mail::GPG;
+
+sub EscapeArobase {
+ my $esc = shift;
+ if ($esc =~ /^([-\@\w.]+)$/) {
+ $esc = $1; # $data now untainted
+ $esc =~ s/@/\\@/;
+ return $esc;
+ }
+}
+
+sub SetMail {
+ print "Mail address: ";
+ my $addr = <STDIN>;
+ if (not Email::Valid->address($addr)){
+ die "\nNot a valid email address.";
+ }
+ chomp $addr;
+ return $addr;
+}
+
+sub DbGetLine {
+ my ($dbh, $query) = @_;
+ my $prep = $dbh->prepare( $query );
+ my $exec = $prep->execute() or die $DBI::errstr;
+
+ if ($exec < 0){
+ print $DBI::errstr;
+ }
+
+ while (my @rows = $prep->fetchrow_array()) {
+ my $row = $rows[0];
+ return $row;
+ }
+}
+
+sub MakeGPGDir {
+ my $homedir = shift;
+ make_path($homedir) unless -d $homedir;
+ chmod(0700, $homedir);
+ if(not -e "$homedir/gpg.conf"){
+ open my $out, '>', "$homedir/gpg.conf" or die "[MakeGPGDir function] Can't open $homedir/gpg.conf: $!";
+ print $out "use-agent\n";
+ print $out "charset utf-8\n";
+ print $out "no-escape-from-lines\n";
+ print $out "trust-model always\n";
+ print $out "personal-digest-preferences SHA512 SHA384 SHA256 SHA224\n";
+ print $out "default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 BZIP2 ZLIB ZIP Uncompressed";
+ close $out;
+ }
+}
+
+sub GetRFC822Date {
+ # https://stackoverflow.com/a/40149475, Daniel VÃritÃ
+ use POSIX qw(strftime locale_h);
+ my $old_locale = setlocale(LC_TIME, "C");
+ my $date = strftime("%a, %d %b %Y %H:%M:%S %z", localtime(time()));
+ setlocale(LC_TIME, $old_locale);
+ return $date;
+}
+
+delete @ENV{qw(IFS PATH CDPATH BASH_ENV)};
+$ENV{'PATH'} = q{bin_path_goes_here};
+
+my $HAS_MAILSERVER = q{0};
+my $EMAIL_NOTIF = q{0};
+my $cgi = CGI->new;
+if (not defined $mail){
+ $mail = scalar $cgi->param('mailaddr');
+}
+my $mailfield = q{mailfield_goes_here};
+my $mailsender = q{sender_addr_goes_here};
+my $mailsender_pw = q{sender_pw_goes_here};
+my $mailsender_smtp = q{smtp_domain_goes_here};
+my $mailsender_port = q{smtp_port_goes_here};
+my $isadmin = q{is_admin_goes_here};
+my $db_path = q{db_path_goes_here};
+my $GNUPGHOME = q{gpg_homedir_goes_here};
+my $TEST_GPGHOME = q{test_gpgdir_goes_here};
+my $dbh = DBI->connect("DBI:SQLite:dbname=$db_path", undef, undef, { RaiseError => 1})
+ or die $DBI::errstr;
+chomp $mail;
+my $nick = $cgi->param('username');
+chomp $nick;
+my $pw = $cgi->param('pw');
+my $pw2 = $cgi->param('pw2');
+my $gpgpubk = $cgi->param('gpgpubk');
+$gpgpubk =~ tr/\r//d;
+my ($err, $smtp) = undef;
+
+my $pwmatch = $pw cmp $pw2;
+
+if ($ENV{REQUEST_METHOD} eq 'POST'){
+ if (length($gpgpubk) eq 0){
+ $err = q{<span id="failure">No public GPG key text found !</span>};
+ }
+
+ if (not $pwmatch eq 0){
+ $err = q{<span id="failure">Passwords don't match</span>};
+ }
+
+ if (length($pw) eq 0 or length($pw) < 10){
+ $err = q{<span id="failure">Password can't be empty or less than 10 characters !</span>};
+ }
+
+ if(length($nick) < 0){
+ $nick = $mail;
+ }
+ else{
+ if(length($nick) > 255){
+ $err = q{<span id="failure">Username is too long (more than 255 characters).</span>};
+ }
+
+ if(length($nick) > 0 and length($nick) < 255){
+ #we need to check if duplicate username in db
+ if($nick =~ /^([\w\'\s_]+)$/){
+ $nick = $1;
+ my $dbnick = DbGetLine($dbh, qq{SELECT name from pigeons where name="$nick";});
+ chomp $dbnick;
+ my $samenick = $nick cmp $dbnick;
+ if($samenick == 0){
+ $err = q{<span id="failure">Username is already taken.</span>};
+ }
+ }
+ else{
+ $err = q{<span id="failure">Username must be left blank or contains alphanumeric characters, space(s) and single quotes.</span>};
+ }
+ }
+ }
+
+ if (not Email::Valid->address($mail)){
+ $err = q{<span id="failure">Invalid mail address !</span>};
+ }
+ else {
+ my $dbmail = DbGetLine($dbh, qq{SELECT mail from pigeons where mail='$mail';});
+ chomp $dbmail;
+ my $samemail = $dbmail cmp $mail;
+ if ($samemail == 0){
+ $err = q{<span id="failure">Mail is already taken.</span>};
+ }
+ }
+
+ if (not defined $err){
+ my $str_rand_obj = String::Random->new;
+ my $val = $str_rand_obj->randregex('\w{64}');
+ MakeGPGDir($TEST_GPGHOME);
+ my $pubkfile="$TEST_GPGHOME/$val-public.key.asc";
+ open my $out, '>', $pubkfile or die "$!";
+ print $out $gpgpubk;
+ close $out;
+ `gpg --homedir $TEST_GPGHOME --import $pubkfile`;
+ my $gpgmail = Mail::GPG->new(
+ gnupg_hash_init => {homedir=>$TEST_GPGHOME},
+ debug => 0,
+ no_strict_7bit_encoding =>1,
+ );
+ my $escaddr = EscapeArobase($mail);
+ my $keyid = `gpg --homedir $TEST_GPGHOME --with-colons -k $escaddr | grep "pub:" | cut -d':' -f5`;
+ if ($keyid =~ /([\w]+)/ and length($keyid) eq 16){
+ $keyid = $1;
+ }
+
+ if (not defined $keyid){
+ $err = q{<span id="failure">Email and the public GPG key text doesn't match.</span>};
+ }
+ else{ # this is where we can begin to insert data in db
+ MakeGPGDir($GNUPGHOME);
+ `gpg --homedir $GNUPGHOME --import $pubkfile`,
+ my $gpgmail = Mail::GPG->new(
+ gnupg_hash_init => {homedir => $GNUPGHOME},
+ no_strict_7bit_encoding => 1,
+ debug => 0,
+ ) or die "$!";
+
+ my $rfc822date = GetRFC822Date();
+ my $mimentity = MIME::Entity->build(
+ Date => $rfc822date,
+ From => $mailsender,
+ To => $mail,
+ Charset => 'utf-8',
+ Subjet => "Your GPIGEON Account registration was successful !",
+ Data => ["Hello,\n\tYour GPIGEON account has been successfully created.\n\tHere's your account details:\n\n\t\tUsername: $mail\n\t\tNickname: $nick\n\t\tPassword: $pw\t\nYou can connect through our website, https://$ENV{HOSTNAME}.\n\nThank you,\nGPIGEON Mailer"]);
+ my $encrypted_mime_blob = $gpgmail->mime_encrypt(entity => $mimentity, recipients => [$keyid]) or die;
+ my $encrypted_mime = $encrypted_mime_blob->as_string;
+ my $salt = `openssl rand 16`;
+ my $hash = argon2id_pass($pw, $salt, 3, '32M', 1, 32);
+ $dbh->do(qq{INSERT INTO pigeons VALUES( ?, '$mail', '$nick', '$hash', '$keyid', $adminflag)}) or die $DBI::errstr;
+ $dbh->disconnect;
+
+ if ($EMAIL_NOTIF){
+ use Net::SMTP;
+ use Net::SMTPS;
+ if ($HAS_MAILSERVER){
+ $smtp = Net::SMTP->new(Host => 'localhost');
+ }
+ else {
+ $smtp = Net::SMTPS->new($mailsender_smtp, Port => $mailsender_port, doSSL => 'ssl', Debug_SSL => 0);
+ $smtp->auth($mailsender, $mailsender_pw) or die "$!";
+ }
+
+ $smtp->mail($mailsender) or die "Net::SMTP module has broke: $!";
+ if ($smtp->to($mail)){
+ $smtp->data($encrypted_mime);
+ $smtp->dataend();
+ $smtp->quit();
+ }
+ else {
+ die $smtp->message();
+ }
+ }
+
+ }
+ rmtree($TEST_GPGHOME, {keep_root=>1, safe=>1});
+ }
+}
+
+print 'Content-Type: text/html; charset=utf-8',"\n\n",
+qq{<!DOCTYPE HTML>
+<html>
+<head>
+ <link rel="icon" sizes="48x48" type="image/ico" href="/favicon.ico">
+ <meta charset="utf-8">
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+ <meta name="viewport" content="width=device-width">
+ <title>GPIGEON - Registration form</title>
+ <link rel="stylesheet" href="/styles.css">
+</head>
+<body>
+ <h1>GPIGEON - Registration form</h1>
+ <hr>
+ <form method="POST">
+ <table id="inviteform">
+ <tbody>
+ <tr>
+ <td id="labels">Mail adress:</td>
+ <td>$mailfield</td>
+ </tr>
+ <tr>
+ <td id="labels">(Optional) Username:</td>
+ <td><input placeholder="Choose an username" type="text" name="username"></td>
+ </tr>
+ <tr>
+ <td id="labels">Password:</td>
+ <td><input placeholder="Type a password" type="password" name="pw" required></td>
+ </tr>
+ <tr>
+ <td id="labels">Password (confirmation):</td>
+ <td><input placeholder="Type again your password" type="password" name="pw2" required></td>
+ </tr>
+
+ <br>
+
+ <tr>
+ <td id="gpgpklabel">GPG public key:</td>
+ <td><textarea placeholder="Paste here the result of the command:\ngpg -a --export your\@mailaddre.ss" id="gpgpubk" wrap="off" name="gpgpubk" required></textarea></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td id="loginerr">$err</td>
+ <tr id="createaccbtn">
+ <td></td>
+ <td><input id="accbtn" type="submit" value="Create account"></td>
+ </tr>
+ </tbody>
+ </table>
+ <hr>
+ </form>
+</body>
+</html>};
diff --git a/link-tmpl-template.cgi b/link-tmpl-template.cgi
index 2f5ab0b..3b612c3 100644
--- a/link-tmpl-template.cgi
+++ b/link-tmpl-template.cgi
@@ -150,7 +150,7 @@ qq{<!DOCTYPE html>
$form_error_notif
<label for="filechoice" id="msgbelow">
(Optional) file upload:
- <input id="filechoice" type="file" name="file">
+ <input id="filechoice" type="file" name="fupload">
</label>
<input id="sendbtn" type="submit" value="Send">
</form>
diff --git a/styles.css b/styles.css
index 759edb0..75f226b 100644
--- a/styles.css
+++ b/styles.css
@@ -1,180 +1,274 @@
html{
- background-color:#87CEEB
+ background-color: #87CEEB
}
body{
- font-family:sans-serif;
- width:80%;
- margin:auto;
- font-size:12pt;
+ font-family: sans-serif;
+ width: 80%;
+ margin: auto;
+ font-size: 12pt
}
h1, #msgbelow{
- display:block;
- text-align:center;
+ display: block;
+ text-align: center
}
#linkstable tr th{
- padding:10px;
- font-size:110%;
- margin:0;
- border: 3px solid black;
- border-bottom:none;
+ margin: 0;
+ padding: 10px;
+ font-size: 110%;
+ border: 3px solid black;
+ border-bottom: none
+}
+
+#adminprom, #mailnotif{
+ display: block;
+ padding: 3px
+}
+
+#mailnotif-check, #adminprom-check{
+ float: left
}
#linkstable td{
- text-align:center;
- padding: 5px ;
+ padding: 10px;
+ text-align: center
}
#linkstable input{
- padding:10px;
- margin:5px;
- margin-top:10px;
+ padding: 10px;
+ margin: 5px;
+ margin-top: 10px
}
#linkstable table{
- margin-top:10px;
- border: 1px solid black;
+ margin-top: 10px;
+ border: 1px solid black
}
#linkstable td{
- border:1px solid black;
+ border: 1px solid black
}
-#logoutbtn {
- display: inline;
- float:right;
- top: 0;
- right: 0;
- position:absolute;
+#logoutbtn, #adminpanbtn {
+ display: inline;
+ float: right;
+ top: 0;
+ right: 0;
+ position: absolute
+}
+
+#adminpanbtn {
+ right: 110px
}
#msg{
- display:block;
- margin-left:auto;
- margin-right:auto;
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
border: 1px solid black;
overflow: -moz-scrollbars-none;
- resize:vertical;
- width:50%;
- -ms-overflow-style:none;
+ resize: vertical;
+ width: 50%;
+ -ms-overflow-style: none
}
#msg::-webkit-scrollbar {
- width: 0 !important
+ width: 0 !important
}
#success {
- color:green;
+ color: green
}
#failure {
- color:red;
+ color: red
}
-#loginbox #loginerr{
- border:none;
- margin-right:auto;
- margin-left:auto
+#loginbox, #inviteform{
+ border: none;
+ margin-right: auto;
+ margin-left: auto
}
-#loginbox input {
- width:100%;
+#loginbox input, #inviteform input{
+ width: 100%;
padding: 5px;
- line-height:25px;
+ line-height: 25px
+}
+
+#labels{
+ text-align: right;
+ border: none
+}
+#loginbox tr, #inviteform tr{
+ border: none
}
-#loginbox td {
- text-align:right;
- border:none;
+#inviteform textarea {
+ height: 400px
}
-#loginbox tr {
- border:none;
+#gpgpklabel {
+ text-align: right;
+ display: block /*so the label is display at the top*/
}
-#authbtn td {
- text-align:center;
+td #gpgpubk{
+ display: block;
+ width: 400px;
+ height: 250px;
+ resize: none
}
-#authbtn input {
- width:100px;
+#authbtn td, #createaccbtn td, #loginerr{
+ text-align:center
}
-#mailfied {
- padding: 10px
+#authbtn input, #createaccbtn input{
+ width: 100px
+}
+
+#mailfield {
+ padding: 10px
+}
+
+#genlinkbtn-mob,#geninvbtn-mob {
+ display: none
}
#refreshbtn, #deletelinkbtn, #deleteallbtn,
-#logoutbtn, #genlinkbtn, #sendbtn {
- border-radius:0
- border:3px outset silver;
- padding:15px;
- margin:5px;
+#logoutbtn, #loginbtn, #genlinkbtn, #sendbtn,
+#accbtn, #adminpanbtn, #geninvbtn, #geninvbtn-mob{
+ cursor: pointer;
+ border-radius: 0;
+ border: 3px outset silver;
+ padding: 15px;
+ margin: 5px
+}
+
+#refreshbtn:active, #deletelinkbtn:active,
+#deleteallbtn:active, #genlinkbtn:active, #genlinkbtn-mob:active,
+#sendbtn:active, #accbtn:active,
+#logoutbtn:active, #loginbtn:active,
+#adminpanbtn:active{
+ border: 3px inset silver
}
#mailfield {
- padding: 10px;
+ padding: 10px
+}
+
+#loginerr {
+ text-align: center
+}
+
+#accbtn {
+ height: 50px
+}
+
+#sendbtn , #accbtn{
+ display: block;
+ width: 20%;
+ margin-left: auto;
+ margin-right: auto
}
+#linkstable a:hover{
+ opacity: 0.3;
+ background: white
+}
+
+
@media screen and (max-width: 740px) {
body {
- font-size:0.8em;
- }
+ margin: 0;
+ font-size: 0.8em
+ }
- h1{
- font-size:1.5em;
- }
+ h1{
+ text-align: left;
+ font-size: 1.5em
+ }
+
+ #inviteform, #loginbox{
+ margin: 0
+ }
+
+ #inviteform td , #loginbox td{
+ display: block;
+ text-align: left
+ }
+
+ #inviteform textarea{
+ margin: 0;
+ font-size: 9px;
+ width: 150px;
+ height: 200px
+ }
- #linkstable th,td{
- padding:3px;
- }
+ #linkstable td{
+ margin: 0;
+ padding: 0px;
+ font-size: 10px
+ }
- #linkstable input{
- padding:4px;
- margin:2px;
- margin-top:10px;
+ #linkstable tr,
+ #linkstable th, #linkstable input{
+ margin: 0;
+ padding: 0px
}
-
- #loginbox input{
+
+ #loginbox input, #inviteform input{
padding: 2px;
- line-height:15px;
- }
-
- #logoutbtn {
- float:none;
- top:unset;
- right:unset;
- position:revert;
- }
-
- #mailfield{
- padding: 3px;
- }
-
- #msg {
- width:50%;
- margin:0;
- }
-
- #msgbelow {
- text-align:left;
- }
-
- #refreshbtn, #deletelinkbtn, #deleteallbtn,
- #logoutbtn, #genlinkbtn, #sendbtn {
- padding: 8px
- }
-
- #genlinkbtn{
- display:block
- }
-
- #sendbtn {
- display:inline
- }
+ line-height: 15px
+ }
+
+ #logoutbtn, #adminpanbtn {
+ float: none;
+ top: unset;
+ right: unset;
+ position: revert
+ }
+
+ #mailfield{
+ padding: 3px
+ }
+
+ #msg {
+ width: 50%;
+ margin: 0
+ }
+
+ #msgbelow {
+ text-align: left
+ }
+
+ #refreshbtn, #deletelinkbtn, #deleteallbtn,
+ #logoutbtn, #genlinkbtn, #geninvbtn-mob, #sendbtn, #adminpanbtn{
+ padding: 8px
+ }
+
+ #genlinkbtn, #geninvbtn-mob{
+ display: block
+ }
+
+ #geninvbtn{
+ display: none
+ }
+
+ #sendbtn {
+ margin: 0;
+ display: inline;
+ width: 100px
+ }
+
+ #mailnotif, #mailnotif input, #adminprom, #adminprom input{
+ display: block;
+ padding: 10px
+ }
}