RegLogServer object fields and methods
RegLogServer_object.Rmd
About R6 and specifically RegLogServer Class
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:
- all modules available in shiny.reglog are R6 classes:
- RegLogServer
- dbConnectors - which are used by every RegLogServer to communicate with database containing your user data.
- RegLogDBIConnector
- RegLogGsheetConnector
- mailConnectors - which are used by every RegLogServer to send emails to users of your ShinyApp.
- RegLogEmayiliConnector
- RegLogGmailConnector
- vanilla RegLogConnector, that you can use to create your own Connector class with inheritance.
- R6 objects after initialization have public elements, that can be accessed with
$
. 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:
RegLogServer <- RegLogServer$new(
dbConnector = dbConnector,
mailConnector = mailConnector)
State of user in current ShinyApp session
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.
Check if the user in current session is logged in
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!"))
}
})
Current ID of the user
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()
).
uuid::UUIDgenerate()
#> [1] "eb26b882-2dc3-4cbd-b4c9-20f60cbf99e5"
After login it contains the username that the user have chosen during registration procedure.
RegLogServer$user_id()
Email address of the currently logged user
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 (""
).
RegLogServer$user_mail()
Account ID of the logged user
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).
- value of the id column in the account table for SQL databases
- row number - 1 (header) in the account spreadsheet for googlesheet database.
RegLogServer$account_id()
User logout
You can insert an event to logout user by calling public method.
# if you create an actionButton "logout_button" in your UI, you can observe
# its action and logout after press:
observeEvent(input$logout_button, {
RegLogServer$logout()
})
UI object lists
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 tags -
UI_list_register
containing elements of register procedure tags -
UI_list_credsEdit
containing elements of credentials edit procedure tags -
UI_list_resetPass
containing elements of reset password procedure tags
Message
message
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:
-
time: numeric representation of
Sys.time()
when it was generated - type: indicates the type of the process during which the message was generated
- data: list containing data that was send with this message. Values contained there can be specific to certain type of the message
-
logcontent: all RegLogConnectorMessages send by and received by the RegLogServer object (and by every RegLogConnector) are appended to that object
log
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: ping
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:
- data: response_time: time between receiving the ping message and sending this message back
- logcontent: for message upon initialization it will hold value “init”.
Type: login_front
Type of the message generated by RegLogServer object itself. Contains information about invalidity of values provided during login procedure by user. It contains:
-
data
- success: boolean -
FALSE
- input_provided: boolean -
FALSE
- success: boolean -
This message type is binded with default modalDialogs:
- login_noInput (
input_provided == FALSE
)
Type: login
Type of the message received from the database connectors with responses about login procedure. It contains:
-
data:
- success: boolean -
TRUE
if the login was successful - username: boolean -
TRUE
if the username exists in the database - password: boolean -
TRUE
if the password provided match -
user_id: character - contains user_id presented afterwards in the
RegLogServer$user_id()
. Only ifsuccess == TRUE
-
user_mail: character - contains user_mail presented afterwards in the
RegLogServer$user_mail()
. Only ifsuccess == TRUE
- success: boolean -
-
logcontent:
- brief information with username provided by the user and if the login was successful.
This message type is binded with default modalDialogs:
- login_badId (
data$success == FALSE && data$username == FALSE
) - login_badPass (
data$success == FALSE && data$password == FALSE
) - login_success (
data$success == TRUE
)
Type: register_front
Type of the message generated by RegLogServer object itself. Contains information about invalidity of values provided during register procedure by user. It contains:
-
data:
- success: boolean -
FALSE
- input_provided: boolean -
TRUE
if all needed inputs were provided - valid_id: boolean -
TRUE
if provided user ID was valid - valid_email: boolean -
TRUE
if provided email was valid - valid_pass: boolean -
TRUE
if provided password was valid - identical_pass: boolean -
FALSE
(it is the last condition checked)
- success: boolean -
This message type is binded with default modalDialogs:
- register_noInput (
data$input_provided == FALSE
) - register_nonValidId (
isFALSE(data$valid_id)
) - register_nonValidEmail (
isFALSE(data$valid_email)
) - register_nonValidPass (
isFALSE(data$valid_pass)
) - register_notIndenticalPass (
isFALSE(data$identical_pass)
)
Type: register
Type of the message received from the database connector with responses about register procedure. It contains:
-
data:
- success: boolean -
TRUE
if the register was successful - username: boolean -
TRUE
if there were no conflicts with existing usernames in the database - email: boolean -
TRUE
if there were no conflicts with existing e-mails in the database -
user_id: character - contains user ID with which new user have been registered. Only if
success == TRUE
-
user_mail: character - contains e-mail with which new user have been registered. Only if
success == TRUE
- success: boolean -
-
logcontent:
- registered user ID and mail if the register was successful or value of the element which caused conflict.
This message type is binded with default modalDialogs:
- register_existingId (
data$success == FALSE && data$username == FALSE
) - register_existingEmail (
data$success == FALSE && data$email == FALSE
) - register_success (
data$success == TRUE
)
Type: credsEdit_front
Type of the message generated by RegLogServer object itself. Contains information about invalidity of values provided during credentials change procedure by user. It contains:
-
data:
- success: boolean -
FALSE
(generated only when something is invalid) - user_logged: boolean -
TRUE
if user is currently logged in - input_provided: boolean -
TRUE
if required inputs are not empty - valid_id: boolean -
TRUE
if provided user ID was valid - valid_email: boolean -
TRUE
if provided email was valid - valid_pass: boolean -
TRUE
if provided password was valid - identical_pass: boolean -
FALSE
(it is the last condition checked)
- success: boolean -
This message type is binded with default modalDialogs:
- credsEdit_notLogged (
data$user_logged == FALSE
) - credsEdit_noInput_pass (
isFALSE(data$input_provided) && change == "pass"
) - credsEdit_noInput_other (
isFALSE(data$input_provided) && change == "other"
) - credsEdit_nonValidId (
isFALSE(data$valid_id)
) - credsEdit_nonValidEmail (
isFALSE(data$valid_email)
) - credsEdit_nonValidPass (
isFALSE(data$valid_pass)
) - credsEdit_notIdenticalPass (
isFALSE(data$identical_pass)
)
Type: credsEdit
Type of the message received from the database connector with responses about credentials edit procedure. It contains:
-
data:
- success: boolean -
TRUE
if credentials edit was successful - username: boolean -
TRUE
if provided username was found - password: boolean -
TRUE
if provided password was correct -
new_username: boolean -
TRUE
if provided new ID weren’t in database (no conflicts). Only if there were some conflict. -
new_mail: boolean -
TRUE
if provided new e-mail weren’t in database (no conflicts). Only if there were some conflict. - new_user_id: character - contains new user ID. Only if user ID was changed.
- new_user_mail: character - contains new user e-mail. Only if user mail was changed.
-
new_user_pass: boolean -
TRUE
. Only if user password was changed.
- success: boolean -
-
logcontent:
- brief information about changes.
This message type is binded with default modalDialogs:
- credsEdit_badId (
data$success == FALSE && data$username == FALSE
) - credsEdit_badPass (
data$success == FALSE && data$password == FALSE
) - credsEdit_existingId (
data$success == FALSE && isFALSE(data$username)
) - credsEdit_existingEmail (
data$success == FALSE && isFALSE(data$email)
) - credsEdit_success (
data$success == TRUE
)
Type: resetPass_front
Type of the message generated by RegLogServer object itself. Contains information about invalidity of values provided during password reset procedure by user. It contains:
-
data
- success: boolean -
FALSE
(message generated only when something is invalid) - step: character - either
generate
orconfirm
, depending on the step of the process - input_provided: boolean -
TRUE
if the inputs required for specific step were provided - valid_pass: boolean -
TRUE
if provided password was valid - identical_pass: boolean -
FALSE
(it is the last condition checked)
- success: boolean -
This message type is binded with default modalDialogs:
- resetPass_noInput_generate (
data$step == "generate" && isFALSE(data$input_provided)
) - resetPass_noInput_confirm (
data$step == "confirm" && isFALSE(data$input_provided)
) - resetPass_nonValidPass (
isFALSE(data$valid_pass)
) - resetPass_notIdenticalPass (
isFALSE(data$identical_pass)
)
Type: resetPass_generate
Type of the message received from the database connector with responses about password reset procedure - code generation step. It contains:
-
data:
- success: boolean -
TRUE
if reset code was created successfully - username: boolean -
TRUE
if the username was found in the database - email: character - email to which the reset code will be sent
- success: boolean -
-
logcontent:
- information about user for whom the reset code was generated and to which email it will be sent.
This message type is binded with default modalDialog:
- resetPass_badId (
data$username == FALSE
) - resetPass_codeGenerated (
data$success == TRUE
)
Type: resetPass_confirm
Type of the message received from the database connector with responses about password reset procedure - code confirmation step. It contains:
-
data
- success: boolean -
TRUE
if the password was changed successfully - username: boolean -
TRUE
if the username was found in the database - code_valid: boolean -
TRUE
if the reset code was valid (both matched and not expired)
- success: boolean -
-
logcontent
- username for which the password was changed.
This message type is binded with default modalDialogs:
- resetPass_badId (
data$username == FALSE
) - resetPass_nonValidCode (
isFALSE(data$code_valid)
) - resetPass_success (
data$success == TRUE
)
Type: logout
Type of the message generated by RegLogServer itself, indicating that the user have been logged out. It contains:
-
data
- success: boolean -
TRUE
if the user was logged in and have been logged out
- success: boolean -
-
logcontent
- username of the user that had logged out
This message type is binded with default modalDialog:
- logout_notLogIn (
data$success == FALSE
) - logout_success (
data$success == TRUE
)
Mail message
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.
Type: reglog_mail
This type of message is received after default e-mail sending from all RegLog processess. It contains:
-
data
- process: character - name of the process for which e-mail was sent. Either ‘register’, ‘credsEdit’ or ‘resetPass’
- success: boolean -
TRUE
if the email was sent sucessfully
-
logcontent
- username and address to which email was sent, and the name of the process that triggered it. If
success == FALSE
it will also contain error message.
- username and address to which email was sent, and the name of the process that triggered it. If
Type: custom_mail
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"
)
})
Collected logs during the App session
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:
- time when the message was generated
-
session in which the message was generated (taken from
session$token
) - type of the message
-
note in which the
logcontent
of the message is saved
Configuring RegLogServer
As the whole RegLog system is created with elasticity in mind, there are also many options for customizing the behaviour of RegLogServer object.
Customizing messages and texts
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, useRegLog_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 asFALSE
, 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 ) )
Options related to log saving
There are two options that can be defined in the script that relates to the log collection: RegLogServer.logs that defines saving logs to RegLogServer$logs
and RegLogServer.logs_to_database that defines saving the logs into table or spreadsheet created for log-recording purposes.
To save logs into database, remember to firstly create a table or spreadsheet. During tables creation with either
DBI_tables_create
orgsheet_tables_create
specify argumentuse_log = T
.
To define options just insert in the beginning of your script:
# examples with default values
options("RegLogServer.logs" = 1)
options("RegLogServer.logs_to_database" = 0)
Possible values:
- 0: no message is saved into logs/database
- 1: messages sent and received are saved
- 2: all messages are saved
It isn’t recommended to save any logs into database when using RegLogGsheetConnector as your database driver. All actions made on the googlesheets database are taking significant time. Recommended only during testing/debugging runs.
Options related to e-mail sending
By default, RegLogServer will trigger an e-mail send to users of your ShinyApp after they are registered, when they attempt reset password procedure (to provide them with their reset code) and after changing their user ID or e-mail during the credentials edit procedure.
As the e-mail sending is mandatory during reset password procedure, there is no option to inhibit it, but the other messages are only recommended as they are enriching the user experience. If you are concerned with the amount of e-mails that can be sent from your app, you can inhibit these messages using following options:
options("RegLogServer.register_mail" = FALSE)
options("RegLogServer.credsEdit_mail" = FALSE)
To inhibit all e-mail sending (eg. if the app is under development, you are debugging it or only playing with the package currently), you can pass an RegLogConnector
object to the mailConnector
argument during initialization of the RegLogServer:
RegLog <- RegLogServer$new(
dbConnector = somedbConnector,
mailConnector = RegLogConnector$new()
)