R6 is the alternative class system available for R users. It is more driven towards Object Oriented Programming vs Functional Programming that is most known to R users via built-in S3 class system.
R6 is ideal for creating more complex systems - it keeps all their elements enclosed in their own environment. Most of R users actually uses R6 objects on daily basis: eg. the whole Shiny system is built as system of R6 objects.
Basically, all there is to know about R6 system in regards to shiny.reglog usage is, that:
$
. They can be either fields,
holding some values, or methods containing functions.If you want to get to know more about R6 system as a whole I advise you to check out articles created by R6 maintainers. Below I will talk more thoroughly about RegLogServer class and its public fields and methods.
There are multiple public elements to RegLogServer. To keep them in order, I will describe them on basis of their usage. In all code chunks I will refer to them as if they would be called from an object assigned as RegLogServer:
Elements described there are the most important things that every
creator of ShinyApp that incorporates shiny.reglog should be
using to profit from user login. All of them are
reactiveVal
objects, so you can observe
their
changes and to access their current value you need to include them with
parentheses.
is_logged
is a simple boolean value to check if the user
in current session is logged in (TRUE
) or not
(FALSE
)
# observe the reactiveVal change
observeEvent(RegLogServer$is_logged, {
# if contains TRUE: user is currently logged-in
if (RegLogServer$is_logged()) {
showModal(modalDialog(title = "You are logged in!"))
# if contains FALSE: user isn't logged-in
} else {
showModal(modalDialog(title = "You are not logged in!"))
}
})
user_id
field (character string): unique user ID. When
the user isn’t logged it contains generated at the start of the session
(or after logout) Universally Unique Identifier (with the use
of uuid::UUIDgenerate()
).
After login it contains the username that the user have chosen during registration procedure.
user_mail
field (character string): unique user email.
When the user is logged in, it contains the email that is currently
associated with their user_id. Otherwise, it contains empty
character string (""
).
account_id
field (character string): unique account ID.
It provides the simple way to relate to the specific logged users in
other, custom tables in the database (eg.: settings saved for specific
users).
You can insert an event to logout user by calling public method.
There are dedicated functions for creating UI for different
functionalities of the RegLog system:
RegLog_login_UI
, RegLog_register_UI
,
RegLog_credsEdit_UI
and RegLog_resetPass_UI
.
They put whole default tagLists
into the UI, though.
It is expected that there will be users who would want more freedom
with how their UI should look like. That’s why there are dedicated
public fields containing named lists of UI elements for all of these
functionalities. You can use these to create your own, custom
renderUI
output.
UI_list_login
containing elements of login procedure
tagsUI_list_register
containing elements of register
procedure tagsUI_list_credsEdit
containing elements of credentials
edit procedure tagsUI_list_resetPass
containing elements of reset password
procedure tagsmessage
field is another reactiveVal
value
that can be used to observe any change of the
RegLogServer object state. It always contains most recent
object of S3 class RegLogConnectorMessage,
that the RegLogServer received from its dbConnector or
was specifically generated to communicate specific status changes.
Messages received from mailConnector aren’t exposed in this field. Instead, they are exposed in
RegLogServer$mail_message()
field. They are separated because they don’t idicate a change in state of RegLog system itself - instead, they just show the feedback from mail sending service.
Creation of custom logic depending on its change isn’t at all necessary. It can be handy especially when for any reason you want to inhibit the default modalDialogs that are called by RegLogServer to inform end-user about consequences of their actions (eg. successful login or unsuccessful, because the inputed user ID or password is incorrect).
Every RegLogConnectorMessage is specific type of list and can contain up to four elements:
Sys.time()
when it was generatedlog
field. Content there will be saved as a note in the logs.Below I want to characterize all types of
RegLogConnectorMessages that can be exposed in the
RegLogServer$message()
field. Besides them there are also
messages that are send by the RegLogServer to its
Connectors. To learn more about these, read vignette
Creating custom RegLogConnector handlers.
Conditions for every default modalDialog are written in the order they should be checked in for best results. Conditions written like
value == FALSE
can be checked like that - the message of given type always contains this object. Conditions written likeisFALSE(value)
means that the specified value in the message can beNULL
.
Type of the message that is produced by all classes inheriting from
RegLogConnector upon their initialization, making it also the
very first available in RegLogServer$message()
field.
Received message of this type contains:
Type of the message generated by RegLogServer object itself. Contains information about invalidity of values provided during login procedure by user. It contains:
FALSE
FALSE
This message type is binded with default modalDialogs:
input_provided == FALSE
)Type of the message received from the database connectors with responses about login procedure. It contains:
TRUE
if the login was
successfulTRUE
if the username exists in the
databaseTRUE
if the password provided
matchRegLogServer$user_id()
. Only if
success == TRUE
RegLogServer$user_mail()
. Only if
success == TRUE
This message type is binded with default modalDialogs:
data$success == FALSE && data$username == FALSE
)data$success == FALSE && data$password == FALSE
)data$success == TRUE
)Type of the message generated by RegLogServer object itself. Contains information about invalidity of values provided during register procedure by user. It contains:
FALSE
TRUE
if all needed inputs
were providedTRUE
if provided user ID was
validTRUE
if provided email was
validTRUE
if provided password was
validFALSE
(it is the last
condition checked)This message type is binded with default modalDialogs:
data$input_provided == FALSE
)isFALSE(data$valid_id)
)isFALSE(data$valid_email)
)isFALSE(data$valid_pass)
)isFALSE(data$identical_pass)
)Type of the message received from the database connector with responses about register procedure. It contains:
TRUE
if the register was
successfulTRUE
if there were no conflicts
with existing usernames in the databaseTRUE
if there were no conflicts with
existing e-mails in the databasesuccess == TRUE
success == TRUE
This message type is binded with default modalDialogs:
data$success == FALSE && data$username == FALSE
)data$success == FALSE && data$email == FALSE
)data$success == TRUE
)Type of the message generated by RegLogServer object itself. Contains information about invalidity of values provided during credentials change procedure by user. It contains:
FALSE
(generated only when something
is invalid)TRUE
if user is currently logged
inTRUE
if required inputs are
not emptyTRUE
if provided user ID was
validTRUE
if provided email was
validTRUE
if provided password was
validFALSE
(it is the last
condition checked)This message type is binded with default modalDialogs:
data$user_logged == FALSE
)isFALSE(data$input_provided) && change == "pass"
)isFALSE(data$input_provided) && change == "other"
)isFALSE(data$valid_id)
)isFALSE(data$valid_email)
)isFALSE(data$valid_pass)
)isFALSE(data$identical_pass)
)Type of the message received from the database connector with responses about credentials edit procedure. It contains:
TRUE
if credentials edit was
successfulTRUE
if provided username was
foundTRUE
if provided password was
correctTRUE
if provided new
ID weren’t in database (no conflicts). Only if there were some
conflict.TRUE
if provided new
e-mail weren’t in database (no conflicts). Only if there were some
conflict.TRUE
. Only if user
password was changed.This message type is binded with default modalDialogs:
data$success == FALSE && data$username == FALSE
)data$success == FALSE && data$password == FALSE
)data$success == FALSE && isFALSE(data$username)
)data$success == FALSE && isFALSE(data$email)
)data$success == TRUE
)Type of the message generated by RegLogServer object itself. Contains information about invalidity of values provided during password reset procedure by user. It contains:
FALSE
(message generated only when
something is invalid)generate
or
confirm
, depending on the step of the processTRUE
if the inputs required
for specific step were providedTRUE
if provided password was
validFALSE
(it is the last
condition checked)This message type is binded with default modalDialogs:
data$step == "generate" && isFALSE(data$input_provided)
)data$step == "confirm" && isFALSE(data$input_provided)
)isFALSE(data$valid_pass)
)isFALSE(data$identical_pass)
)Type of the message received from the database connector with responses about password reset procedure - code generation step. It contains:
TRUE
if reset code was created
successfullyTRUE
if the username was found in
the databaseThis message type is binded with default modalDialog:
data$username == FALSE
)data$success == TRUE
)Type of the message received from the database connector with responses about password reset procedure - code confirmation step. It contains:
TRUE
if the password was changed
successfullyTRUE
if the username was found in
the databaseTRUE
if the reset code was valid
(both matched and not expired)This message type is binded with default modalDialogs:
data$username == FALSE
)isFALSE(data$code_valid)
)data$success == TRUE
)Type of the message generated by RegLogServer itself, indicating that the user have been logged out. It contains:
TRUE
if the user was logged in and
have been logged outThis message type is binded with default modalDialog:
data$success == FALSE
)data$success == TRUE
)mail_message
field contains last
RegLogConnectorMessage received from mailConnector. It
only provides information about last process of sending email, which
don’t signalize the change of the data or state of current login
session, so it is separated from much more important
message
field.
This type of message is received after default e-mail sending from all RegLog processess. It contains:
TRUE
if the email was sent
sucessfullysuccess == FALSE
it will also
contain error message.This type of message isn’t received during regular RegLog run. It is a response to message that you can use to send a custom e-mail. It contains the same responses as reglog_mail message.
To send a custom email using mailConnector, pass to its listener a RegLogConnectorMessage of type custom_mail, as in example below:
# you can observe some kind of event to trigger the send
observeEvent(input$send_custom_email, {
# as the username and email will be acquired from RegLogServer,
# it is best to make sure that the user is logged-in
req(RegLogServer$is_logged())
message_to_send <- RegLogConnectorMessage(
type = "custom_mail",
# name your process in some unique way - it will be tracked by the app
# and saved into logs
process = "attachement_mail!",
# username and email can be gotten from RegLogServer
username = RegLogServer$user_id(),
email = RegLogServer$user_mail(),
# we can specify the subject and body of message ourselves
mail_subject = "Custom message with attachement",
# it's best for the body to contain html code
mail_body = "<p>This is a custom message send from my App</p>
<p>It is completely optional, but that kind of message can also
contain an attachment!</p>",
# optionally: attachment
mail_attachement = "files/myplot.png"
)
})
During the lifespan of the session, RegLogServer object
sends, shows and receives many different
RegLogConnectorMessages. By default, all messages
send to its dbConnector and
mailConnector and received back are saved into
the RegLogServer$logs
field, into separate lists per
direction. There are also some messages that are only
shown by the object (namely all messages with “_front”
suffix and message of type logout)
They contain following information:
session$token
)logcontent
of the
message is savedAs the whole RegLog system is created with elasticity in mind, there are also many options for customizing the behaviour of RegLogServer object.
During RegLogServer object initialization you can specify some arguments:
app_name
- name of your application that will show
up in default emails sent to your users. Defaults to the name of root
folder of your application.
app_address
- URL to your application that will show
up in default emails sent to your users. Defaults to the URL that the
App is accessed on the client side (actually: NULL
, as the
address is got on session start)
lang
- language in which the default texts are
presented. Defaults to “en” for English. You can also specify “i18” for
the RegLog to show only the content identifiers for ease of building
your own translations using external tools, eg. shiny.i18n.
custom_txts
- defaults to NULL. Can be a named list
of character vectors that should be used in place of defined text for
language of your choosing (to check them out, use
RegLog_texts()
function).
You can define custom texts during initialization of RegLogServer:
# initialize new RegLogServer object
RegLog <- RegLogServer$new(
# assign created dbConnector and mailConnector
dbConnector = dbConnector,
mailConnector = mailConnector,
# replace default title and body of `login_success` modalDialog
custom_txts = list(
login_success_t = "Welcome!",
login_success_b = "Hi! It's nice to see you logged into our ShinyApp!"
)
)
use_modals
- defaults to TRUE. If specified as
FALSE
, no default modals will be shown. You can also
inhibit only specific modal dialogs by providing named list of FALSE
values. Eg:
# initialize new RegLogServer object
RegLog <- RegLogServer$new(
# assign created dbConnector and mailConnector
dbConnector = dbConnector,
mailConnector = mailConnector,
# inhibit default 'login_success' and 'register_success' modals
use_modals = list(
login_success = FALSE,
register_success = FALSE
)
)