. "${_EXEC}/cgilite/session.sh"
. "${_EXEC}/cgilite/storage.sh"
-USER_REGISTRATION="${USER_REGISTRATION:-true}"
-USER_REQUIREEMAIL="${USER_REQUIREEMAIL:-true}"
+SENDMAIL=${SENDMAIL-sendmail}
+
+USER_REGISTRATION="${USER_REGISTRATION-true}"
+USER_REQUIREEMAIL="${USER_REQUIREEMAIL-true}"
+USER_ACCOUNTPAGE="${USER_ACCOUNTPAGE}"
+
+USER_ACCOUNTEXPIRE="${USER_ACCOUNTEXPIRE:-$((86400 * 730))}"
+USER_CONFIRMEXPIRE="${USER_CONFIRMEXPIRE:-86400}"
+
+MAILFROM="${MAILDOMAIN-noreply@${HTTP_HOST%:*}}"
HTTP_HOST="$(HEADER Host)"
-MAILFROM="${MAILDOMAIN:-noreply@${HTTP_HOST%:*}}"
-user_db="${_DATA}/users.db"
-unset USER_ID USER_NAME USER_EMAIL
+[ "$HTTPS" ] && SCHEMA=https || SCHEMA=http
+
+# == FILE FORMAT ==
+# UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
+# (pending|active|deleted)
+
+# == GLOBALS ==
+UNSET_USER='unset \
+ USER_ID USER_NAME USER_STATUS USER_EMAIL USER_PWSALT USER_PWHASH \
+ USER_EXPIRE USER_DEVICES USER_FUTUREUSE
+'
+
+LOCAL_USER='local \
+ USER_ID USER_NAME USER_STATUS USER_EMAIL USER_PWSALT USER_PWHASH \
+ USER_EXPIRE USER_DEVICES USER_FUTUREUSE
+'
+
+unset USER_IDMAP
+eval "$UNSET_USER"
+
+user_db="${user_db:-${_DATA}/users.db}"
-# USER DB
-# UID UNAME STATUS (pending|active|deleted) EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
+read_user() {
+ local user="$1"
-user_init(){
- local user_id="$(SESSION_VAR user_id)"
- local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
- [ "$user_id" ] \
- && read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE <<-EOF
- $(grep "^${user_id} " "$user_db")
+ # Global exports
+ USER_ID='' USER_NAME='' USER_STATUS='' USER_EMAIL='' USER_PWSALT=''
+ USER_PWHASH='' USER_EXPIRE='' USER_DEVICES='' USER_FUTUREUSE=''
+
+ if [ $# -eq 0 ]; then
+ read -r USER_ID USER_NAME USER_STATUS USER_EMAIL USER_PWSALT USER_PWHASH \
+ USER_EXPIRE USER_DEVICES USER_FUTUREUSE
+ elif [ "$user" -a -f "$user_db" -a -r "$user_db" ]; then
+ read -r USER_ID USER_NAME USER_STATUS USER_EMAIL USER_PWSALT USER_PWHASH \
+ USER_EXPIRE USER_DEVICES USER_FUTUREUSE <<-EOF
+ $(grep "^${user} " "${user_db}")
EOF
- [ "$STATUS" -a "$EXPIRE" ] \
- && if [ "$STATUS" = active -a "$EXPIRE" -gt "$_DATE" ]; then
- USER_ID="$UID"
- USER_NAME="$(UNSTRING "$UNAME")"
- USER_EMAIL="$(UNSTRING "$EMAIL")"
- fi
+ fi
+ if [ "$USER_ID" -a "${USER_EXPIRE:-0}" -gt "$_DATE" ]; then
+ USER_NAME="$(UNSTRING "$USER_NAME")"
+ USER_EMAIL="$(UNSTRING "$USER_EMAIL")"
+ USER_DEVICES="$(UNSTRING "$USER_DEVICES")"
+ unset USER_PWSALT USER_PWHASH
+ else
+ eval "$UNSET_USER"
+ return 1
+ fi
+}
+
+update_user() {
+ # internal function for user update
+ local uid="$1" uname status email pwsalt pwhash expire devices futureuse
+ local UID_ UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
+ local arg
+
+ for arg in "$@"; do case $arg in
+ uname=*) uname="${arg#*=}";;
+ status=*) status="${arg#*=}";;
+ email=*) email="${arg#*=}";;
+ password=*) pwsalt="$(randomid)"; pwhash="$(user_pwhash "$pwsalt" "${arg#*=}")";;
+ expire=*) expire="${arg#*=}";;
+ devices=*) devices="${arg#*=}";;
+ esac; done
+
+ if LOCK "$user_db"; then
+ while read -r UID_ UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES \
+ FUTUREUSE; do
+ if [ "$UID_" = "$uid" ]; then
+ printf '%s %s %s %s %s %s %i %s %s\n' \
+ "$uid" "$(STRING "${uname-$(UNSTRING "$UNAME")}")" \
+ "${status:-${status-${STATUS}}${status+\\}}" \
+ "${email:-${email-${EMAIL}}${email+\\}}" \
+ "${pwsalt:-${PWSALT}}" "${pwhash:-${PWHASH}}" \
+ "${expire:-$((_DATE + USER_ACCOUNTEXPIRE))}" \
+ "$(STRING "${devices-$(UNSTRING "$DEVICES")}")" \
+ "${FUTUREUSE:-\\}"
+ elif [ "$STATUS" = pending -a ! "$EXPIRE" -ge "$_DATE" ]; then
+ # omit expired invitations from output
+ :
+ else
+ printf '%s %s %s %s %s %s %i %s %s\n' \
+ "$UID_" "$UNAME" "$STATUS" "$EMAIL" "$PWSALT" "$PWHASH" \
+ "$EXPIRE" "$DEVICES" "$FUTUREUSE"
+ fi
+ done <"$user_db" >"${user_db}.$$"
+ mv -- "${user_db}.$$" "$user_db"
+ RELEASE "$user_db"
+ else
+ return 1
+ fi
+}
+
+new_user(){
+ local user="${1:-$(timeid)}"
+ shift 1
+
+ if LOCK "$user_db"; then
+ if grep -q "^${user} " "$user_db"; then
+ RELEASE "$user_db"
+ return 1
+ fi
+ printf '%s \\ %s \\ \\ \\ %i \\ \\\n' \
+ "$user" "pending" "$(( _DATE + USER_CONFIRMEXPIRE ))" >>"$user_db"
+ else
+ return 1
+ fi
+
+ if [ $# -eq 0 ]; then
+ RELEASE "$user_db"
+ return 0
+ elif update_user "$user" "$@"; then
+ return 0
+ else
+ RELEASE "$user_db"
+ return 1
+ fi
+}
+
+user_idmap(){
+ local uid="$1" ret
+ eval "$LOCAL_USER"
+
+ if [ ! "$USER_IDMAP" ]; then
+ while read_user; do
+ USER_IDMAP="${USER_IDMAP}${USER_ID} ${USER_NAME}${BR}"
+ done <"$user_db"
+ fi
+ if [ "$uid" -a "$USER_IDMAP" != "${USER_IDMAP##*${uid} }" ]; then
+ ret="${USER_IDMAP##*${uid} }"; ret="${ret%%${BR}*}";
+ printf '%s\n' "$ret"
+ return 0
+ elif [ "$uid" ]; then
+ return 1
+ else
+ printf '%s' "$USER_IDMAP"
+ return 0
+ fi
+}
+
+user_idof(){
+ local name="$(STRING "$1")" ret
+ [ "$USER_IDMAP" ] || user_idmap >/dev/null
+
+ if [ "${name%\\}" -a "$USER_IDMAP" != "${USER_IDMAP% ${name}${BR}*}" ]; then
+ ret="${USER_IDMAP% ${name}${BR}*}"; ret="${ret##*${BR}}"
+ printf '%s\n' "$ret"
+ return 0
+ else
+ return 1
+ fi
}
user_checkname(){
user_nameexist(){
local uname="$(STRING "$1")"
- local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
+ local UID_ UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
[ -f "$user_db" -a -r "$user_db" ] \
- && while read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE; do
+ && while read -r UID_ UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE; do
[ "$EXPIRE" -gt "$_DATE" -a "$UNAME" = "$uname" ] && return 0
done <"$user_db"
return 1
user_emailexist(){
local email="$(STRING "$1")"
- local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
+ local UID_ UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
[ -f "$user_db" -a -r "$user_db" ] \
- && while read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE; do
+ && while read -r UID_ UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE; do
[ "$EXPIRE" -gt "$_DATE" -a "$EMAIL" = "$email" ] && return 0
done <"$user_db"
return 1
local pwsalt="$(randomid)"
local pw="$(POST pw |grep -m1 -xE '.{6,}' )" pwconfirm="$(POST pwconfirm)"
- if [ "$USER_REGISTRATION" != true ]; then
+ if [ "$USER_REGISTRATION" != true -a -s "$user_db" ]; then
REDIRECT "${_BASE}${PATH_INFO}#ERROR_REGISTRATION_DISABLED"
fi
REDIRECT "${_BASE}${PATH_INFO}#ERROR_EMAIL_INVALID"
elif user_emailexist "$email"; then
REDIRECT "${_BASE}${PATH_INFO}#ERROR_EMAIL_EXISTS"
- elif LOCK "$user_db"; then
- printf '%s \\ pending %s \\ \\ %i \\ \\\n' \
- "$uid" "$(STRING "$email")" "$(( $_DATE + 86400 ))" \
- >>"$user_db"
- RELEASE "$user_db"
- sendmail -t -f "$MAILFROM" <<-EOF
+ elif new_user "$uid" status=pending email="$email" expire="$((_DATE + USER_CONFIRMEXPIRE))"; then
+ debug "Sending Activation Link:" \
+ "${SCHEMA}://${HTTP_HOST}${_BASE}${PATH_INFO}?user_confirm=${uid}+$(session_mac "$uid")"
+ "$SENDMAIL" -t -f "$MAILFROM" <<-EOF
From: ${MAILFROM}
To: ${email}
Subject: Your account registration at ${HTTP_HOST%:*}
You can activate your account using this link:
- https://${HTTP_HOST%:*}/${_BASE}${PATH_INFO}?user_confirm=${uid}+$(session_mac "$uid")
+ ${SCHEMA}://${HTTP_HOST}${_BASE}${PATH_INFO}?user_confirm=${uid}+$(session_mac "$uid")
- This registration link will expire after 24 hours.
+ This registration link will expire after $((USER_CONFIRMEXPIRE / 3600)) hours.
If you did not request an account at ${HTTP_HOST%:*}, then someone else
probably entered your email address by accident. In this case you shoud
REDIRECT "${_BASE}${PATH_INFO}#ERROR_PW_EMPTYTOOSHORT"
elif [ "$pw" != "$pwconfirm" ]; then
REDIRECT "${_BASE}${PATH_INFO}#ERROR_PW_MISMATCH"
- elif LOCK "$user_db"; then
- printf '%s %s active %s %s %s %i \\ \\\n' \
- "$uid" "$(STRING "$uname")" "$(STRING "$email")" \
- "$pwsalt" "$(user_pwhash "$pwsalt" "$pw")" \
- "$(( $_DATE + 86400 * 730 ))" \
- >>"$user_db"
- RELEASE "$user_db"
-
+ elif new_user "$uid" uname="$uname" status=active email="$email" password="$pw" expire="$((_DATE + USER_ACCOUNTEXPIRE))"; then
SESSION_COOKIE new
SESSION_BIND user_id "$uid"
- REDIRECT "${_BASE}${PATH_INFO}#USER_REGISTER_CONFIRM"
+ if [ "$USER_ACCOUNTPAGE" ]; then
+ REDIRECT "${USER_ACCOUNTPAGE}"
+ else
+ REDIRECT "${_BASE}${PATH_INFO}#USER_REGISTER_CONFIRM"
+ fi
else
REDIRECT "${_BASE}${PATH_INFO}#ERROR_USER_NOLOCK"
fi
fi
}
+user_invite(){
+ local uid="$(timeid)"
+ local email="$(POST email |user_checkemail)"
+ local message="$(POST message)"
+
+ if [ ! "email" ]; then
+ REDIRECT "${_BASE}${PATH_INFO}#ERROR_EMAIL_INVALID"
+ elif user_emailexist "$email"; then
+ REDIRECT "${_BASE}${PATH_INFO}#ERROR_EMAIL_EXISTS"
+ elif new_user "$uid" status=pending email="$email" expire="$((_DATE + USER_CONFIRMEXPIRE))"; then
+ debug "Sending Invitation Link:" \
+ "${SCHEMA}://${HTTP_HOST}${_BASE}${PATH_INFO}?user_confirm=${uid}+$(session_mac "$uid")"
+ "$SENDMAIL" -t -f "$MAILFROM" <<-EOF
+ From: ${MAILFROM}
+ To: ${email}
+ Subject: You have been invited to ${HTTP_HOST%:*}
+
+ ${USER_NAME:-Someone} has offered an invitation to this email address.
+
+ ${message}
+
+ You can create your account using this link:
+
+ ${SCHEMA}://${HTTP_HOST}${_BASE}${PATH_INFO}?user_confirm=${uid}+$(session_mac "$uid")
+
+ This registration link will expire after $((USER_CONFIRMEXPIRE / 3600)) hours.
+
+ If you do not know what this is about, then someone else probably
+ entered your email address by accident. In this case you shoud
+ simply ignore this message and we will remove your email address from
+ our database within the next day.
+
+ This is an automatic email. Any direct reply will not be received.
+ Your Account Registration Robot.
+ EOF
+ REDIRECT "${_BASE}${PATH_INFO}#USER_REGISTER_CONFIRM"
+ else
+ REDIRECT "${_BASE}${PATH_INFO}#ERROR_USER_NOLOCK"
+ fi
+}
+
user_confirm(){
# enable account
- local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
- local uid="$(POST uid |checkid)"
+ eval "$LOCAL_USER"
+ local uid="$(POST uid |checkid || printf invalid)"
local signature="$(POST signature)"
local uname="$(POST uname |user_checkname)"
local pwsalt="$(randomid)"
local pw="$(POST pw |grep -m1 -xE '.{6,}' )" pwconfirm="$(POST pwconfirm)"
+ read_user "${uid}"
+
if [ "$signature" != "$(session_mac "$uid")" ]; then
REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_LINK_INVALID"
elif [ ! "$uname" ]; then
REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_PW_EMPTYTOOSHORT"
elif [ "$pw" != "$pwconfirm" ]; then
REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_PW_MISMATCH"
- elif LOCK "$user_db"; then
- read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE <<-EOF
- $(grep "^${uid} " "$user_db")
- EOF
-
- if [ "$STATUS" != pending -o "$EXPIRE" -le "$_DATE" ]; then
- RELEASE "$user_db"
- REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_LINK_INVALID"
+ elif [ "$USER_STATUS" != pending -o \! "$USER_EXPIRE" -gt "$_DATE" ]; then
+ REDIRECT "${_BASE}${PATH_INFO}?${QUERY_STRING}#ERROR_LINK_INVALID"
+ elif update_user "$USER_ID" uname="$uname" status=active password="$pw"; then
+ SESSION_COOKIE new
+ SESSION_BIND user_id "$USER_ID"
+ if [ "$USER_ACCOUNTPAGE" ]; then
+ REDIRECT "${USER_ACCOUNTPAGE}"
else
- printf '%s %s active %s %s %s %i %s %s\n' \
- "$UID" "$(STRING "$uname")" "$EMAIL" \
- "$pwsalt" "$(user_pwhash "$pwsalt" "$pw")" \
- "$(( $_DATE + 86400 * 730 ))" "$DEVICES" "$FUTUREUSE" \
- >"${user_db}.$$"
- grep -v "^${uid} " "$user_db" >>"${user_db}.$$"
- mv "${user_db}.$$" "${user_db}"
- RELEASE "$user_db"
-
- SESSION_COOKIE new
- SESSION_BIND user_id "$UID"
- REDIRECT "${_BASE}${PATH_INFO}#USER_REGISTER_CONFIRM"
+ REDIRECT "${_BASE}${PATH_INFO}?user_register=confirm#USER_REGISTER_CONFIRM"
fi
else
REDIRECT "${_BASE}${PATH_INFO}#ERROR_USER_NOLOCK"
# set cookie
# keep logged in - device cookie?
# initialize new session!
- local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
+ local UID_ UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
local uname="$(POST uname |STRING)" pw="$(POST pw)"
[ -f "$user_db" -a -r "$user_db" ] \
- && while read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE; do
+ && while read -r UID_ UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE; do
if [ "$UNAME" = "$uname" -o "$EMAIL" = "$uname" ]; then
if [ "$STATUS" = active -a "$EXPIRE" -gt "$_DATE" -a "$PWHASH" = "$(user_pwhash "$PWSALT" "$pw")" ]; then
SESSION_COOKIE new
- SESSION_BIND user_id "$UID"
+ SESSION_BIND user_id "$UID_"
REDIRECT "${_BASE}${PATH_INFO}#USER_LOGGED_IN"
fi
fi
}
user_update(){
- # passphrase, email
- :
+ # todo: username update, email update / email confirm
+ local UID_ UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
+ # local uname="$(POST uname |STRING)"
+ local uid oldpw pw pwconfirm
+
+ uid="$(POST uid)"
+ oldpw="$(POST oldpw)"
+ pw="$(POST pw |grep -xE '.{6}')"
+ pwconfirm="$(POST pwconfirm)"
+
+
+ read -r UID_ UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE <<-EOF
+ $(grep "^${uid} " "$user_db")
+ EOF
+
+ if [ "$UID_" = "$USER_ID" -a "$PWHASH" = "$(user_pwhash "$PWSALT" "$oldpw")" ]; then
+ if [ "$pw" -a "$pw" = "$pwconfirm" ]; then
+ update_user "${uid}" password="$pw"
+ REDIRECT "${_BASE}${PATH_INFO}#UPDATE_SUCCESS"
+ else
+ REDIRECT "${_BASE}${PATH_INFO}#ERROR_PWMISMATCH"
+ fi
+ elif [ "$UID_" = "$USER_ID" ]; then
+ REDIRECT "${_BASE}${PATH_INFO}#ERROR_INVALID_AUTH_PASSWORD"
+ else
+ REDIRECT "${_BASE}${PATH_INFO}#ERROR_NOTLOGGEDIN"
+ fi
}
+
user_recover(){
# send recover link
:
:
}
-user_init
+read_user "$(SESSION_VAR user_id)"
+[ "$USER_STATUS" -a "$USER_STATUS" != active ] && eval $UNSET_USER
[ "$REQUEST_METHOD" = POST ] && case "$(POST action)" in
user_register) user_register ;;
user_confirm) user_confirm ;;
+ user_invite) user_invite ;;
user_login) user_login ;;
user_logout) user_logout ;;
- user_update)
- :;;
+ user_update) user_update ;;
user_recover)
:;;
user_disable)
:;;
esac
+export USER_ID USER_NAME USER_STATUS USER_EMAIL USER_PWSALT USER_PWHASH \
+ USER_EXPIRE USER_DEVICES USER_FUTUREUSE
+
+
+w_user_update(){
+ if [ ! "$USER_ID" ]; then
+ cat <<-EOF
+ [div #user_update .nouser
+ This page can only be used by registered users
+ ]
+ EOF
+ else
+ cat <<-EOF
+ [form #user_update method=POST
+ [hidden "uid" "$USER_ID"]
+ [p .username Logged in as $USER_NAME]
+ [input type=password name=oldpw placeholder="Current Passphrase"]
+ [input type=password name=pw placeholder="New Passphrase" pattern=".{6,}"]
+ [input type=password name=pwconfirm placeholder="Confirm New Passphrase" pattern=".{6,}"]
+ [submit "action" "user_update" Update Passphrase]
+ ]
+ EOF
+ fi
+}
+
w_user_register(){
if [ "$(GET user_confirm)" ]; then
w_user_confirm
- elif [ "$USER_REGISTRATION" != true ]; then
+ elif [ "$USER_REGISTRATION" != true -a -s "$user_db" ]; then
cat <<-EOF
[div #user_register .disabled
User Registration is disabled.
elif [ "$USER_REQUIREEMAIL" != true ]; then
cat <<-EOF
[form #user_register .registername method=POST
- [input name=uname placeholder="Choose Username" tooltip="Your username may contain any character but the @ sign. It must be at least 3 characters long, and it must start with a letter." pattern="^\[a-zA-Z\]\[a-zA-Z0-9 -~\]{2,127}$" autocomplete=off]
+ [input name=uname placeholder="Choose Username" tooltip="Your username may contain any character but the @ sign. It must be at least 3 characters long, and it must start with a letter." pattern="^\[\\\\p{L}\]\[\\\\p{L}0-9 -~\]{2,127}$" autocomplete=off]
[input type=password name=pw placeholder="Choose Passphrase" pattern=".{6,}"]
[input type=password name=pwconfirm placeholder="Confirm Passphrase" pattern=".{6,}"]
[submit "action" "user_register" Sign Up]
}
w_user_confirm(){
- local UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
+ local UID_ UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE
local user_confirm="$(GET user_confirm)"
local uid="${user_confirm% *}" signature="${user_confirm#* }"
if [ "$signature" = "$(session_mac "$uid")" ]; then
- read -r UID UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE <<-EOF
+ read -r UID_ UNAME STATUS EMAIL PWSALT PWHASH EXPIRE DEVICES FUTUREUSE <<-EOF
$(grep "^${uid} " "$user_db")
EOF
if [ "$STATUS" = pending -a "$EXPIRE" -gt "$_DATE" ]; then
[form #user_confirm method=POST
[input type=hidden name=uid value="${uid}"]
[input type=hidden name=signature value="${signature}"]
- [input disabled=disabled value="$(HTML "$EMAIL")"]
- [input name=uname placeholder="Choose Username" tooltip="Your username may contain any character but the @ sign. It must be at least 3 characters long, and it must start with a letter." pattern="^\[a-zA-Z\]\[a-zA-Z0-9 -~\]{2,127}$" autocomplete=off]
+ $([ "$EMAIL" != '\' ] && printf \
+ '[input disabled=disabled value="%s" placeholder="Email"]' "$(UNSTRING "$EMAIL" |HTML)"
+ )
+ [input name=uname placeholder="Choose Username" tooltip="Your username may contain any character but the @ sign. It must be at least 3 characters long, and it must start with a letter." pattern="^\[\\\\p{L}\]\[\\\\p{L}0-9 -~\]{2,127}$" autocomplete=off]
[input type=password name=pw placeholder="Choose Passphrase" pattern=".{6,}"]
[input type=password name=pwconfirm placeholder="Confirm Passphrase" pattern=".{6,}"]
[submit "action" "user_confirm" Finish Registration]
fi
}
+w_user_invite(){
+ local uid invlink
+
+ if [ "$(GET user_confirm)" ]; then
+ w_user_confirm
+ elif [ "$USER_ID" -a "$SENDMAIL" ]; then
+ cat <<-EOF
+ [form #user_invite method=POST
+ [input placeholder="Email Recipient" name=email autocomplete=off]
+ [textarea name="message" placeholder="Message to recipient" . ]
+ [submit "action" "user_invite" Send Invitation]
+ ]
+ EOF
+ elif [ "$USER_ID" ]; then
+ uid="$(timeid)"
+ new_user "$uid" status=pending expire="$((_DATE + USER_CONFIRMEXPIRE))"
+ invlink="${SCHEMA}://${HTTP_HOST}${_BASE}${PATH_INFO}?user_confirm=${uid}+$(session_mac "$uid")"
+ debug "New Invitation Link: $invlink"
+ cat <<-EOF
+ [div #user_invite .link
+ [p An anonymous user account has been set up. Send the following link to the intended user, so they may claim their account. The link will remain valid for $((USER_CONFIRMEXPIRE / 3600)) hours.]
+ [a href="$(HTML "$invlink")" . $(HTML "$invlink")]
+
+ [p [a href="#" . Set up another account]]
+ ]
+ EOF
+ else
+ cat <<-EOF
+ [div #user_invite .notallowed
+ Only registered users may send an invitation to another user.
+ ]
+ EOF
+ fi
+}
+
w_user_login(){
if [ ! "$USER_ID" ]; then
cat <<-EOF