Starting the UGC Webapp
You can start the ugc by executing ugc.jar either directly or by calling java -jar ugc.jar which is an executable. Additionally, it provides a web interface to view the user data and export it. JVMARGS can be provided either as JAVA_OPTS in an ugc.conf file next to the ugc.jar or as part of the command when using java -jar ugc.jar. The content of an ugc.conf file might be:
JAVA_OPTS='-Xmx1g -Dlogging.config=/cms/ugc/config/logback.xml -Dspring.config.location=/cms/ugc/config/application.yml'
Starting ugc with java would look like this for the same properties:
java -Xmx1g -Dlogging.config=/cms/ugc/config/logback.xml -Dspring.config.location=/cms/ugc/config/application.yml -jar ugc.jar
Configuration
The configuration of the webapp is done with a file called application.yml. It's written in the commonly used YAML format. In this example all values are the default values.
# jvm arguments as a single string
vmargs : "-Xmx1g"
# all configuration parameters regarding the connection to the sophora server
sophora-server :
# the user the ugc webapp should use to login into sophora
username : null
# password for this user
password : null
# address of the sophora server (i.e. "http://localhost:1196")
host : null
# if you want to use a proxy, the hostname or ip address of the proxy
proxyHost : null
# the name of the proxy user
proxyUser : null
# the password of the proxy user
proxyPassword : null
# port of the proxy server
proxyPort : 0
# number of connection retries
connectRetries : 3
# time between connection retries
connectRetryInterval : 10
# directory of the slaves.xml that holds the information on the sophora cluster
slavesInfoDir : ""
# configuration of the database connection
database :
# url of the jdbc connection, the last part is the name of the datadase (i.e. "jdbc:mysql://localhost:3306/usercontent")
url : null
# username for database
user : null
# password for database
password : null
# enable jpa caching
jpaCache : false
# configuration of caching
caching :
# url of the cache servlet
cacheServerletUrl : null
# path to cache servlet without url and context path
cacheServletPostfix : null
# the delivery group for the flush action
cacheServletGroup : null
# password for the cache servlet
cacheServletPassword : null
# delay invalidation tasks by X seconds
invalidationRequestDelay : 30
# configuration for sending e-mails
# since 4.0.2
email :
# configuration of the smtp server
transport :
# hostname/address
host : "localhost"
# port
port : 25
# user for smtp
# if the user and password properties are null, no authentication is attempted.
user : null
# password
# if the user and password properties are null, no authentication is attempted.
password : null
# use starttls
starttls : true
# additional JavaMail Session properties
properties: {}
# configuration of the double opt in mechanism
double-opt-in :
# configuration of the template message for the e-mail
template :
# from field
from : null
# subject field
subject : "Please verify your email address"
# reply to field
replyTo : null
# cc field
cc : null
# bcc field
bcc : null
# configuration of the smtp server
# Deprecated since 4.0.2, please use email.transport instead
# transport :
# host : "localhost"
# port : 25
# user : null
# password : null
# starttls : true
# configuration of the confirmation via e-mail
# since 4.0.2
confirmation :
# configuration of the template message for the e-mail
template :
# from field
from : null
# subject field
subject : null
# reply to field
replyTo : null
# cc field
cc : null
# bcc field
bcc : null
# configuration of comments
comment :
# list of all content types as string that should support this feature
primaryTypes : [ ]
# how many comments should be allowed per ip address in 10 seconds?
limitPerTenSeconds : 1
# how many comments should be allowed per ip address in a minute?
limitPerMinute : 2
# how many comments should be allowed per ip address in a day?
limitPerDay : 100
# is the multiuser feature enabled?
multiUserEnabled : "true"
# the image variant of the image of an editor
avatarVariant : "small"
# the primaryType of the editor
editorNodetype : "sophora-ugc-nt:ugcEditor"
# the property name of the avatar image of the editor
editorAvatarProperty : "sophora-ugc:avatar"
# the property name of the name of the editor
editorNameProperty : "sophora-ugc:name"
# the maximal allowed size for the headline. Values between 0 and 65135 are permitted.
headlineSize : 255
# the maximal allowed size for the content.Values between 0 and 65135 are permitted.
contentSize : 1000
# additional space in the field content to edit.Values between 0 and 400 are permitted.
editTolerance : 0
# configuration of the spam list that is used for comments
spam-list :
# the multi string property of the spam list document with the spam words in it
spamWordsProperty : "sophora-ugc:spamWords"
# primary type of the spam list document
primaryType : "sophora-ugc-nt:spamList"
# external ID of the spam list document
externalId : "49bc5b8c-f37e-45a4-9cc3-c16b38f3b569"
# configuration of form submissions
form :
# the form field that should be treated as e-mail field
formFieldName_Email : "email"
# the boolean property that defines if double opt in is active
doubleOptInProperty : "sophora-ugc:useDoubleOptIn"
# the string property that is used for the body of the double opt in message
optInEmailTextProperty : "sophora-ugc:emailText"
# the string property for the subject of the double opt in message
optInEmailSubjectProperty : "sophora-ugc:emailSubject"
# the boolean property that defines if confirmation via e-mail is active
confirmationEmailProperty : "sophora-ugc:enableConfirmationEmail"
# the string property that is used for the body of the confirmation message
confirmationEmailTextProperty : "sophora-ugc:confirmationEmailText"
# the string property for the subject of the confirmation message
confirmationEmailSubjectProperty : "sophora-ugc:confirmationEmailSubject"
# the child node of the form fields
formFieldsChildnode : "sophora-ugc:formFields"
# the string property of the field name
fieldNameProperty : "sophora-extension:formfieldname"
# the string property of the field style (E-Mail, Text)
fieldStyleProperty : "sophora-extension:fieldstyle"
# the string property of the label
labelProperty : "sophora-extension:question"
# the boolean property that says if the field is required
requiredProperty : "sophora-extension:formrequired"
# string property for the headline of the form
headlineProperty : "sophora-ugc:title"
# the node type of the form
primaryType : "sophora-ugc-nt:form"
# prefer the form wizard property to the childnode to get the form fields
useFormWizard : true
# string property for the form wizard data
formWizardProperty : "sophora-ugc:formWizard"
# list of field types that should not appear in the backend
blacklistedFieldTypes : ["submit","button","reset"]
# the regular expression and the associated validation error message for the search
form-search:
formDataSearchRegex: ".+"
validationErrorMsg: "Ungültige Eingabe"
# the search results are cached. The maximum number of results in the cache is configured here. If the cache is full and a different search request is made, the result that has not been used the longest is replaced.
numberOfResultsCached: 14
# every 15 minutes, all cache entries are deleted that were not used for the time (ms) defined here
removeAfter: 7200000 # 2h
# configuration of image uploads
image-upload :
# list of all content types as string that should support this feature
primaryTypes : [ ]
# how many image uploads should be allowed per ip address in 10 seconds?
limitPerTenSeconds : 1
# how many image uploads should be allowed per ip address in a minute?
limitPerMinute : 2
# how many image uploads should be allowed per ip address in a day?
limitPerDay : 100
# the proposal section where newly imported images are listed
proposalSection : "User-Bilder"
# node type of images that should be imported into sophora
imageNodeType : "sophora-extension-nt:image"
# configuration of ratings
rating :
# list of all content types as string that should support this feature
primaryTypes : [ ]
# how many ratings should be allowed per ip address in 10 seconds?
limitPerTenSeconds : 1
# how many ratings should be allowed per ip address in a minute?
limitPerMinute : 2
# how many ratings should be allowed per ip address in a day?
limitPerDay : 100
# configuration of quizzes
quiz :
# the form field that should be treated as e-mail field
formFieldName_Email : "email"
# the string property of the answer text
answerTextProperty : "sophora-ugc:text"
# the string property of the answer uuid
answerUuidProperty : "sophora-ugc:uuid"
# the long property with the points for an answer
answerPointsProperty : "sophora-ugc:points"
# the string property with the description of an answer
answerCommentProperty : "sophora-ugc:description"
# the boolean property that determines if an answer is correct
answerIsCorrectProperty : "sophora-ugc:isCorrect"
# the string property with the text of a question
questionTextProperty : "sophora-ugc:text"
# the child node with the answers for a question
questionAnswersChildnode : "sophora-ugc:answers"
# string property for the headline of the quiz
headlineProperty : "sophora-ugc:title"
# the child node of the quiz questions
questionsChildnode : "sophora-ugc:questions"
# the reference property of the form
formProperty : "sophora-ugc:form"
# primary type of quizzes
primaryType : "sophora-ugc-nt:quiz"
# configuration of votings
voting :
# form field that should be treated as e-mail field
formFieldName_Email : "email"
# string property for the headline of the voting
headlineProperty : "sophora-ugc:title"
# reference property of the form
formProperty : "sophora-ugc:form"
# primary type of votings
primaryType : "sophora-ugc-nt:voting"
# date property with the date until which is property is valid
votingToProperty : "sophora-ugc:validTo"
# long property with the number of votes that are allowed
numberOfVotesProperty : "sophora-ugc:numberOfVotes"
# child node of the voting items
itemsChildnode : "sophora-ugc:votingItems"
# string property with the text of a property
itemTextProperty : "sophora-ugc:text"
# string property with voting item uuid
itemUuidProperty : "sophora-ugc:uuid"
# string property with description of the voting item
itemDescriptionProperty : "sophora-ugc:description"
# string property of the voting that declares the voting type
votingTypeProperty : "sophora-ugc:votingType"
# the default voting type; possible values: "simple", "ranking"
defaultVotingType : "simple"
# number of days after the voting stopped being valid to wait
# until the voting report gets persisted and the user submissions get deleted
timeoutDelay : 30
# interval in seconds to update the internal cache for a voting
cacheUpdateInterval : 240
# evict a cache entry of the internal cache after X minutes without any read access
cacheEvictAfterMinutes : 720
# the total maximum of voting reports in the internal cache
cacheMaxNumberOfCachedReports : 50
# configuration of the manipulation check for forms, quizzes and votings
manipulation :
# multi string property with manipulation criteria
filtersProperty : "sophora-ugc:manipulationFilters"
# long property with numbers of entries allowed per interval
entriesAllowedProperty : "sophora-ugc:entriesAllowed"
# long property with length of the manipulation interval
intervalProperty : "sophora-ugc:manipulationInterval"
# string property for the time unit of an interval
intervalTypeProperty : "sophora-ugc:manipulationIntervalType"
# configure the usage of serial programs
serial-programs :
# (type: bySelectValue)
idProperty : "sophora-ugc:serialProgram"
# property with selectvalue whose content is compared with the value configured in subHierarchydocument (type: bySelectValue)
broadcastType : "sophora-content:broadcastType"
# to configure a hierarchy document to be not a serial program. The select value is used (type: bySelectValue)
subHierarchydocument : "subHierarchydocument"
# the select value document (type: bySelectValue)
externalId : "40b38a3c-dfc0-4e3b-abf2-2bcea73d01b6"
# title for the dropdown menu (type: byDocument)
titleProperty : "sophora-content:title"
# allowed nodetypes (type: byDocument). If the list is empty all nodetypes are allowed. Otherwise, only documents of the specified types can be used.
allowedNodetypes : []
# configuration of the load monitoring
load-information :
# how many load information entries per host should be kept in memory?
entriesPerHost : 10000
# how many days of no new load information until all load data is removed from memory
daysToDeclareDead : 2
# configuration of the embedded jetty server
server :
# http port of the jetty
port : 9080
# respect FORWARD headers
# necessary when using swagger UI behind a reverse procy
forward-headers-strategy: "FRAMEWORK"
# configuration for basic auth. Basic auth is enabled only when name and password are configured
# since 4.2.0
spring:
security:
user:
# the username to authenticate
name: user
# the password to authenticate
password: password
# configuration for the swagger ui
springdoc:
swagger-ui:
url: "/v3/api-docs"
# to disable the default swagger url
disable-swagger-default-url: true
# enable to continue using the Swagger UI when basic authentication is enabled
csrf:
enabled: true
# configuration of some features in the 'Sophora User Feedback Backend'
# this configuration does not affect the functions of the REST API or Swagger UI
features :
# configure the actions an editor can use on comments
actions :
# enables the option to delete all comments submitted by a particular user
enableDeleteByUser : false
# enables the option to overwrite the username
enableOverwriteUsername : false
# enables the option to overwrite the externalUserId
enableOverwriteExternalUserId : false
# enables the option to execute bulk operations on filter
enableActionsByFilter: false
# enables the option to execute the delete bulk operation on filter
enableDeleteByFilter: false
# configuration of the filters
filters :
# show/hide the filter options
documentTypes : true
serialPrograms : false
editors : true
dates : true
status : true
markers: false
# there are currently two types of serial programs / categories to configure: 'byDocument' and 'bySelectValue'. Read the section 'Configure SerialProgram/Category Filter' for detailed information.
serialProgramsType : "bySelectValue"
# the filter name can be adjusted for the special use case of the filter.
serialProgramsName : "Sendungsreihe"
# toggle the feature to write notes for individual comments
notes :
enabled : false
# toggle the feature to pin comments
pinning :
enabled : false
# to configure the marking options, the array of objects must be populated according to the following scheme:
# {
# key : "pr",
# label : "Proofreading",
# colorValue : "#ffff00" # color specification (in an by css accepted way)
# }
#
markers : []
comment-templates :
# toggle the feature to use templates when commenting as an editor
enabled : false
# the node type used for the comment templates
templateNodeType : "sophora-ugc-nt:commentTemplate"
# the structure node under which new created templates are to be located
# If the template feature is enabled, this property must be a valid structure node path
templateStructureNodePath : null
# the ID stem that will be used to create a new template
templateIdStem : "kommentartemplate"
# configure if the app is the main application
isMainApp : false
# the backend for comments and image uploads has links to the preview of the documents in sophora. You can configure the preview url here. (i.e. "http://preview_host:8080/contextpath/system/preview.jsp?sophoraid=")
previewUrl : null
# to get the right property of the title of document that was rated or commented,
# use the property that is most commonly used as title or headline property
simpleDocumentHeadlineProperty : "sophora-content:title"
# this property defines the time in milliseconds to wait between failed startup attempts
# Attention: this is not a configuration parameter of the sophora client
waitingTimeBetweenStartupAttempts : 10000
# the hash values of submissions are stored in the webapp
# a submission whose hash value is already known is sorted out as a duplicate
# this property specifies the maximum number of hashes stored for duplicate checking
maxNumberOfSubmissionsSaved : 500
# this property defines whether embedding the UGC webapp in an iFrame is allowed or not. By default it is not allowed.
iFramesAllowed : false
# Management Port for jolokia/jmx
management :
server :
port : 1694
# username and passwort for jolokia/jmx
jolokia:
username: ""
password: ""
# an allowed origin of the websocket, which is used to check for new content of a UGC instance. Required only when running the ugc editorial UI with a reverse proxy.
websocket:
allowedOrigin: "http://host:port"
The most important configuration is the option isMainApp
. If you run more than one ugc webapp, only one should be configured as main app. The main app is responsible for cleanup in general and for the manipulation check of forms, quizzes and votings.
Authentication
Basic Authentication is enabled when a username and password are specified in the configuration. This is done via the spring.security.user.name
and spring.security.user.password
properties. If these properties are set, you must authenticate yourself to use UGC. The session ends when you close your browser. See the configuration section above for details.
Please keep in mind to provide authentication credentials via sophora.ugc.baseurl
in the configuration of the Taglib and sophora.ugc.submitter.webapp.csrfTokenUrl
in the configuration of the Submitter in your webapp.
Jolokia
Jolokia is started if a management port has been specified in the configuration. This is done using the property management.server.port. With management enabled Jolokia can be accessed using the path jolokia e.g. http://<hostname>:<server.port>/jolokia.
Configure the SerialProgram/Category Filter
There are two versions of the serialProgram filter. These filters are disabled by default because of the required configuration. This filter can be used to create a filter for categories other than serialPrograms. For this use the label of the selection filter can be adjusted with serialProgramsName property in the application.yml.
byDocument
This version is for an implementation in which a corresponding document exists for each serialProgram or category. This filter uses the categoryExternalId field. To use the filter this field must be filled with the corresponding externalIds of the serialProgram/category documents. The documents used by this filter can be restricted by adding nodetypes to the allowedNodetypes list. If the list is empty (default), all node types are allowed.
You can adjust the title of the filter in the ugc-webapp backend via the serialProgramsName
configuration property.
# example configuration
serial-programs :
titleProperty : "sophora-content:title"
allowedNodetypes : []
features :
filters :
serialPrograms : true
serialProgramsType: "byDocument"
serialProgramsName: "Serialprogram"
This filter allows the selection of several values. If the filter will be used via REST interface, the externalIds should be entered individually in the filter map which is included in the page request. Accepted names for the assignment match the regex "category\d*".
Example: "category5" : "categoryExternalId"
bySelectValue
This version uses the SelectValues of the document with the id entered in externalId. This filter uses the serialProgram field into which the value of a SelectValue can be entered.
serial-programs :
idProperty : "sophora-ugc:serialProgram"
broadcastType : "sophora-content:broadcastType"
subHierarchydocument : "subHierarchydocument"
externalId : "40b38a3c-dfc0-4e3b-abf2-2bcea73d01b6"
features :
filters :
serialPrograms : true
serialProgramsType: "bySelectValue"
The externalId is the externalId of the SelectValue Document. The value of the select value has to be insert into the
Configure the size of the headline and content
The maximum size of the fields headline and content can be configured in the application.yml. Values between 0 and 65135 are permitted. If no size is configured, the default value for headline is 255 characters and for content 1000 characters.
In addition, there is the possibility to give the editor additional space in the content field for editing comments. The maximum size for edited comments is {contentSize + editTolerance} characters. Values between 0 (default) and 400 are allowed.
# example configuration
comment:
...
editTolerance: 400
headlineSize: 255
contentSize: 2000
Marking example configuration
In order to mark comments and then filter them, the configuration must be adjusted.
Example configuration with a marker option:
features:
filters:
markers: true
markers: [{
key: "pr",
label: "Proofreading",
colorValue: "#ffff00"
}
]
If a used option is removed and existing comments have the key, the comments are treated as if they had no key. But it is not possible to save comments with an unconfigured key.
Configuration of allowed actions
There are three actions that are not displayed in the webapp by default due to their impact. These actions can still be executed via the rest interface.
features :
actions :
enableDeleteByUser : false
enableOverwriteUsername: false
enableOverwriteExternalUserId: false
enableActionsByFilter: false
enableDeleteByFilter: false
enableOverwriteUsername/enableOverwriteExternalUserId
If these actions are unlocked, there is an input field in the edit view for each unlocked field. The username or externalUserId can then be changed via these input fields in the webapp.
enableActionsByFilter/enableDeleteByFilter
If enableActionsByFilter
is set to true it allows the user to execute bulk operations (accept and deny) on a filtered list of comments. If enableDeleteByFilter
is also set to true, also the delete option is allowed.
Commenting as an Editor
To comment as an editor, the multiuser feature must be enabled (multiUserEnabled: "true").
Furthermore a valid editorNodetype (editorNodetype) must be provided. The editorNodetype must contain at least a string property for the name (editorNameProperty) and a property for the avatar (editorAvatarProperty). The avatar childnode contains a reference to an image document. For the avatar an image variant (avatarVariant) must be provided. It can be any of the image variants.
To use the feature there must be at least one published document of the editorNodetype.
The mixin sophora-ugc-mix:ugcEditor and the example nodetype sophora-ugc-nt:ugcEditor for the editorNodetype is provided with the imports.
Property | Description |
---|---|
multiUserEnabled | Enable the multiUser feature (boolean) |
avatarVariant | Name of an valid image variant |
editorNodetype | Primary type of the editorNodetype |
editorNameProperty | Property name of the name property defined in the editorNodetype |
editorAvatarProperty | Property name of the avatar property defined in the editorNodetype |
Forms
There are two ways to model form fields in Sophora:
- as childnodes using the form fields input field type or a dynamic table
- as String property using the form wizard input field type
The ugc webapp needs to be configured to understand how you decided to model forms. The configuration parameter form.formWizardProperty
decides which String property is interpreted as form wizard input field. The configuration parameter form.useFormWizard
tells the webapp, if this property should be used to get the form fields. If the value of the property is blank or form.useFormWizard
is set to false, the ugc webapp tries to get the form fields from the childnode configured in form.formFieldsChildnode
.
Voting Items and Quiz Answers
In the configuration there are two configuration parameters that have similar importance:
voting.itemUuidProperty
quiz.answerUuidProperty
These parameters define properties that represent UUIDs for the quiz answers and the voting items. This means that a property needs to be configured for each of these childnodes. The best way to achieve this is via document changing script that assures that this property is set for each childnode.
Example Script for Voting Items
class SaveVotingItemListener implements IScriptDocumentChangeListener {
private Logger log;
public void documentChanging(IScriptDocumentChangeEvent event) {
// use the primary type of your voting here
if (event.getStateChange().equals(DocumentChangedEvent.StateChange.NONE) && event.getDocument().getPrimaryType().equals("sophora-ugc-nt:voting")) {
INode node = event.getDocument();
// use the name of the cildnode of the voting items here
for(INode answer : node.getNodesByName("sophora-ugc:votingItems")) {
// use the uuid property of the voting item childnode here
if(!answer.hasProperty("sophora-ugc:uuid")) {
// and here
answer.setString("sophora-ugc:uuid",UUID.randomUUID().toString());
}
}
}
}
public void init(IScriptContext context) {
log = context.getLogger();
log.info("Logging started");
}
public void destroy() {
log.info("Logging stopped");
}
}
return new SaveVotingItemListener();
Example Script for Quiz items
class SaveQuizAnswerListener implements IScriptDocumentChangeListener {
private Logger log;
public void documentChanging(IScriptDocumentChangeEvent event) {
// use the primary type of your quiz here
if (event.getStateChange().equals(DocumentChangedEvent.StateChange.NONE) && event.getDocument().getPrimaryType().equals("sophora-ugc-nt:question")) {
INode node = event.getDocument();
// use the name of the cildnode of the quiz answers here
for(INode answer : node.getNodesByName("sophora-ugc:answers")) {
// use the uuid property of the answer childnode here
if(!answer.hasProperty("sophora-ugc:uuid")) {
// and here
answer.setString("sophora-ugc:uuid",UUID.randomUUID().toString());
}
}
}
}
public void init(IScriptContext context) {
log = context.getLogger();
log.info("Logging started");
}
public void destroy() {
log.info("Logging stopped");
}
}
return new SaveQuizAnswerListener();
Configuration of the Full-Text Search
The regular expression and the associated validation error message for the search can be configured in the application.yml.
# Configuration example: limitation on email addresses
form-search:
formDataSearchRegex: "^[\\w._%+-]+@[\\w.-]+\\.[\\w]{2,6}$"
validationErrorMsg: "Bitte geben sie eine valide Emailadresse als Suchbegriff ein."
Cleanup
When a document gets deleted the user generated content gets deleted as well.
Votings have a more sophisticated behaviour. On deletion, the voting report gets persisted before the user submissions get deleted. Additionally, you can set a date until which the voting is valid (voting.votingToProperty
) and a delay in days (voting.timeoutDelay
). The delay specifies the number of days to wait after the valid-to date to delete user submissions and persist the voting report.
Caching
When new user submissions change the comments to be displayed or might have changed the voting report or the rating evaluation, invalidation requests for the cache fragments associated with the user generated content get sent. In order to prevent many requests from damaging the performance of the web application, the invalidation requests get bundled. The administration webapp waits a configurable amount of time (caching.invalidationRequestDelay
) before it sends an invalidation request. During this time all other invalidation requests for this document get ignored. In consequence, there is a certain delay before the updated results get visible in your webapp.
To achieve that all fragments on all deliveries get invalidated, Sophora's cache servlet is used. It is crucial that you configure either the URL of the cache servlet or the path to the cache servlet without URL and context path and in both cases the delivery group:(caching.cacheServerletUrl || caching.cacheServletPostfix) && caching.cacheServletGroup
.
Otherwise, this cache invalidation feature is deactivated.
Additionally, there is an internal cache for votings, which can be configured as well. This means that changes in the voting report might take a while until they get updated - even in the UI of the ugc-webapp.
Votings, Quizzes, Forms
Manipulation criteria can be configured per form, quiz or voting document. There are properties usually configured on a dedicated tab where you can configure the following:
- criteria that make up a user. IP address (ipAddress), referrer (referrer), e-mail address (eMail) and user agent (userAgent) are the options. The criteria are connected with AND. I.e., all checked criteria have to be equal in submissions to be considered by the same user
- length of the considered interval for manipulation check
- interval time unit (ms/s/m/h/d)
- number of submissions by the same user that are allowed per interval
If one of these values is not set in the form, quiz or voting document, the voting is considered to be without manipulation control.
If the manipulation control is active, new entries are checked before they are saved in the database. If entries are considered as manipulation attempts according to the criteria, they are discarded and not saved in the database.
If the form, quiz or voting document is published, and there have been changes to the manipulation criteria, all entries for that document will be checked again to determine whether or not they are considered manipulation under the new criteria. If entries are found to be manipulated, they will be flagged and will not be added to the results. Entries that are subsequently recognized as manipulation are not deleted from the database, so that accidental changes to the criteria do not lead to the loss of data for entries that are already in the database.
Comments, Image Uploads, Ratings
For these three features only the IP address is considered to identify malicious attempts. You can limit the number of submissions per:
- ten seconds
- minute
- day
If the number of submissions per IP address and time interval is already exceeded, a new submission for this IP address won't be saved in the database.
Ratings have an additional limit. Only one rating submission is allowed per IP address and rateable document.
Double Opt-In
Double opt-in means that a user has to confirm his submission via e-mail. This addon supports this feature for forms, quizzes and votings. Using this feature for votings has the effect that the submission is not evaluated before the user confirmed the e-mail. For quizzes and forms, double opt-in only has the effect that the submissions are marked differently in the backend.
The double opt-in process consists of three steps:
- The user submits a form, quiz or voting result, including their e-mail address. This is the first opt-in.
- The double opt-in asks the user via e-mail to confirm his input. The e-mail contains a link with a unique ID representing the opt-in request.
- The user confirms the double opt-in request by clicking on the link in the e-mail. This is the second opt-in.
Usage
Double opt-in can be configured in a form document. To enable it for quizzes and votings, add a reference to a form document in your quiz or voting.
The form needs to at least contain a field for the user's e-mail address. The form document must also contain a template for the body of the e-mail. An e-mail template including subject and sender address can be configured globally (see doubleOptIn
in the configuration section above for details). Optionally, you may set a custom subject and a sender e-mail address in each form document.
form.doubleOptInProperty
, form.optInEmailTextProperty
and form.optInEmailSubjectProperty
in the application.yml file. The name of the form field containing the user's e-mail address has to be set in form.formFieldName_Email
. See form
in the configuration section above for details.The body text should contain the placeholder string $opt-in-id$
, which will be replaced with the actual unique ID used to identify the opt-in request. You can also use curly brackets, {opt-in-id}
, to insert the value in URL encoding. Typically, this placeholder will be put at the end of a URL that denotes the link the user has to click. The generated link should point to a request handler that stores the successful opt-in request. Typically this is done using the JSP tag storeDoubleOptIn
(see the Taglibrary documentation page). The ID may also be given to the user as plain text, so he can input it anywhere.
The submitted content may be referenced in the body text as $FIELDNAME$
or URL encoded as {FIELDNAME}
using the (technical) name of a form field. Additional keys for replacements inside the body of the e-mail can be provided to the JSP tags storeForm, storeQuiz and storeVoting as parameter doubleOptInParams
(see the Taglibrary documentation page).
Confirmation mail message
You can enable an automated reply message that users receive via e-mail once they submitted a form, voting or quiz result. The confirmation mail is sent after the data is written to the database, so that the user can use the confirmation mail as a submission receipt.
If double opt-in is enabled, the confirmation mail is sent after succesful submission of the second opt-in.
Usage
The confimation mail can be configured in a form document. To enable it for quizzes and votings, add a reference to a form document in your quiz or voting.
The form needs to at least contain a field for the user's e-mail address. The form document must also contain a template for the body of the e-mail. An e-mail template including subject and sender address can be configured globally (see confirmation
in the configuration section above for details). Optionally, you may set a custom subject and a sender e-mail address in each form document.
The submitted form content may be referenced in the body text as $FIELDNAME$
using the (technical) name of a form field. You can also use curly brackets, {FIELDNAME}
, to insert the values in URL encoding.
form.confirmationEmailProperty
, form.confirmationEmailTextProperty
and form.confirmationEmailSubjectProperty
in the application.yml file. The name of the form field containing the user's e-mail address has to be set in form.formFieldName_Email
. See form
in the configuration section above for details.Admin UI
You can access the backend at the http port configured in the application.yml. E.g.: http://localhost:9080
.
Sophora allows you to configure browser tabs by document types. These browser tabs make it possible to have an exact view on the user generated content on a per document basis.
Type | View | URL |
---|---|---|
Comments | List of all comments | http://HOSTNAME:PORT/#!/comments/${sophora:externalId}?nav=false http://HOSTNAME:PORT/#!/comments/${sophora:id}?nav=false&idType=sophoraId |
Form submissions | List of participants | http://HOSTNAME:PORT/#!/participants/forms/${sophora:externalId}/withResetPermission?nav=false http://HOSTNAME:PORT/#!/participants/forms/${sophora:id}/withResetPermission?nav=false&idType=sophoraId |
Image uploads | List of all image uploads | http://HOSTNAME:PORT/#!/imageUploads/${sophora:externalId}?nav=false http://HOSTNAME:PORT/#!/imageUploads/${sophora:id}?nav=false&idType=sophoraId |
Quizzes | List of participants | http://HOSTNAME:PORT/#!/participants/quizzes/${sophora:externalId}/withResetPermission?nav=false http://HOSTNAME:PORT/#!/participants/quizzes/${sophora:id}/withResetPermission?nav=false&idType=sophoraId |
Votings | List of participants | http://HOSTNAME:PORT/#!/participants/votings/${sophora:externalId}/withResetPermission?nav=false http://HOSTNAME:PORT/#!/participants/votings/${sophora:id}/withResetPermission?nav=false&idType=sophoraId |
Votings | The voting report | http://HOSTNAME:PORT/#!/votingreport/${sophora:externalId}/withResetPermission?nav=false http://HOSTNAME:PORT/#!/votingreport/${sophora:id}/withResetPermission?nav=false&idType=sophoraId |
Swagger UI and OpenAPI Specification
UGC Webapp provides an interactive Swagger UI to document the REST endpoints. The REST API is specified according to the OpenAPI Specification standard. Depending on the http port configured in the application.yml, e.g. 9080, you can access them under the following URLs: