Build an Oracle Content Management VBCS Secure Form Component

You can build a local Oracle Content Management component that uses REST APIs exposed by business objects in VBCS to deliver a simple web form that requires user authentication.

VBCS Configuration

  1. Allow Cross-Origin Resource Sharing (CORS):

    1. Choose Visual Builder , then Settings, and then Allowed Origins.

    2. Click New Origin and enter the URL of your Oracle Content Management server for Origin Address.

    3. Click the check mark to save.

  2. Create a new Application

    .
  3. Configure the app to allow access for authenticated users.

    1. Open Application Settings.

      .
      Description of vbcs_application_settings.png follows
      Description of the illustration vbcs_application_settings.png
    2. On the Settings page, choose User Roles.

    3. Add roles to control access to the business object.

      The values for Mapping are groups from Oracle Identity Cloud Service. To add groups, see Create Groups for Your Organization.

  4. Create a business object.

Build an Oracle Content Management Local Component

Assumptions:

  • The VBCS app name is "RequestForm".

  • The business object name is "requestform" and it contains the following custom fields:

    • name (required)

    • email (required)

    • phone

    • subject

    • message

Modify assets/render.js

  1. Define the component template as follows.

    <!-- ko if: initialized -->
    <div class="form">
    
           <!-- ko if:  requestSuccessMsg -->
           <div class="request-msg green" data-bind="text: requestSuccessMsg"></div>
           <!-- /ko -->
           <!-- ko if:  requestFailMsg -->
           <div class="request-msg red" data-bind="text: requestFailMsg"></div>
           <!-- /ko -->
    
           <label class="required-field" for="name">Name</label>
           <input type="text" id="name" name="name" required placeholder="Your name. . ." data-bind="value: name"/>
    
           <label class="required-field" for="email">Email</label>
           <input type="text" id="email" name="email" required placeholder="Your email. . ." data-bind="value: email"/>
    
           <label for="phone"></label>Phone</label>
           <input type="text" id="phone" name="phone" data-bind="value: phone"/>
    
           <label for="subject">Subject</label>
           <input type="text" id="subject" name="subject" data-bind="value: subject"/>
    
           <label for="message"></label>Message</label>
           <textarea id="message" name="message" rows="6" data-bind="value: message"/>
    
           <button data-bind="click: sendRequest, , enable: canSubmit">Send Request</button>
    </div>
    
    <!-- note that the component has completed rendering into the page -->
    <div class="scs-hidden" data-bind="scsRenderStatus: {'id': id, 'status': 'complete'}"></div>
    <!-- /ko -->
    
  2. Create the observables for the fields in the Knockout ViewModel.

    self.initialized = ko.observable(false);
    self.requestSuccessMsg = ko.observable();
    self.requestFailMsg = ko.observable();
    self.VBCSServerUrl = ko.observable();
    self.name = ko.observable();
    self.email = ko.observable();
    self.phone = ko.observable();
    self.subject = ko.observable();
    self.message = ko.observable();
    
    // Get VBCS server
    var serverPromise = getVBCSServerURL();
        serverPromise.then(function (result) {
        self.VBCSServerUrl(result.url);
        self.initialized(true);
    });
    
    
    self.canSubmit = ko.computed(function () {
    	return self.name() && self.email();
    }, self);
    
  3. Handle required fields.

    Enable the Submit button only after all required fields have values.

  4. Obtain the VBCS connection

    After configure VBCS connection, there are two ways to get the connection:

    • From siteinfo at site runtime

    • From Integrations in Site Builder

      var getVBCSServerURL = function () {
          var serverPromise = new Promise(function (resolve, reject) {
          // First try to get from siteinfo
          var siteConnections = SCSRenderAPI.getSiteProperty('siteConnections'
          var serverUrl = siteConnections && siteConnections.VBCSConnection;
          if (serverUrl) {
              console.log('Get VBCS server from siteinfo: ' + serverUrl);
              resolve({'url': serverUrl});
          } else {
              // Get from integrations
              var configUrl = '/documents/web?IdcService=AF_GET_APP_INFO_SIMPLE&dAppName=VBCS';
                  $.ajax({
                      type: 'GET',
                      dataType: 'json',
                      url: configUrl
                      success: function (data) {
                          var appInfo = data.ResultSets.AFApplicationInfo;
                          var enabled;
                          if (appInfo) {
                              for (var i = 0; i < appInfo.fields.length; i += 1) {
                                  if (appInfo.fields[i].name === 'dAppEndPoint') {
                                      serverUrl = appInfo.rows[appInfo.currentRow][i];
                                  } else if (appInfo.fields[i].name === 'dIsAppEnabled') {
                                      enabled = appInfo.rows[appInfo.currentRow][i];
                                  }
                                  if (serverUrl && enabled) {
                                      break;
                                  }
                              }
                          console.log('Get VBCS server from Idc Service: ' + serverUrl);
                          resolve({'url': serverUrl});
                      },
                      error: function (xhr, status, err) {
                          console.log('Request failed: url:' + configUrl + ' status: ' + status + ' error: ' + err);
                          resolve({'url': serverUrl});
                      }
                  });
              }
          });
          return serverPromise;
      };
  5. Get an authorization token.

    Requirement: Oracle Content Management and VBCS are deployed in the same identity domain.

    var getAuthToken = function (args) {
        // dummy function if callbacks not supplied
        var dummyCallback = function () {};
    
        // extract the args and create the server URL
        var serverURL = (args.serverURL || '/').split('/ic/')[0],
            successCallback = args.successCallback || dummyCallback,
            errorCallback = args.errorCallback || dummyCallback,
            tokenURL = serverURL + ‘/ic/builder/resources/security/token’;
    
        // For VBCS to get the authtoken:
        //  - make a POST call to /ic/builder/resources/security/token
        //  - include scope=run-time form parameter
        var getToken = function (tokenURL, successCallback, errorCallback) {
            $.ajax({
                'type': 'POST',
                'url': tokenURL,
                data: {
                    scope: 'run-time'
                },
                'xhrFields': {
                    withCredentials: true
                 },
                 'success': successCallback
            }).fail(errorCallback);
        };
    
        // try to get the token normally
        getToken(tokenURL,
            function (resp, status, xhr) {
                var ct = xhr.getResponseHeader("content-type") || "";
    
                // if the response was an HTML Form. . .
                if (ct.indexOf('html') > -1) {
                    // parse the form and submit it
                    var parser = new DOMParser(),
                        htmlDoc = parser.parseFromString(resp, "text/html"),
                        forms = htmlDoc.getElementsByTagName("form");
                    if (forms.length === 1) {
                        var f = forms[0];
                        $.ajax({
                            'type': 'POST',
                            'url': f.action,
                            'data': $(f).serialize(),
                            'xhrFields': {
                                'withCredentials': true
                            'success': function () {
                                // retry getting the token now the form was auto-submitted
                                getToken(tokenURL, successCallback, errorCallback);
                            }
                        }).fail(function () {
                            // even if the form submit failed, retry getting the token
                            getToken(tokenURL, successCallback, errorCallback);
                        });
                    }
                } else {
                    // already logged in return the token
                    successCallback(resp);
                }
            },
    	 errorCallback);
    };
  6. Submit the request.

    self.sendRequest = function (data, event) {
        var vbcsServer = self.VBCSServerUrl();
        var authorization, token;
        var appName = 'securerequestform',
            mode = 'rt',
            appVersion = 'live',
            businessObject = 'Requestform';
        var url = vbcsServer + '/' + mode + '/' + appName + '/' + appVersion + '/resources/data/' + businessObject;
        var payload = {
            "name": self.name(),
            "email": self.email(),
            "phone": self.phone(),
            "subject": self.subject(),
            "message": self.message()
        };
        // get token first
        getAuthToken({
            'serverURL': self.VBCSServerUrl(),
            'successCallback': function (data) {
                token = data;
                authorization = (token.token_type ? token.token_type : 'Bearer') + ' ' + token.access_token;
                $.ajax({
                    type: 'POST',
                    url: url,
                    beforeSend: function (xhr) {
                        xhr.setRequestHeader('Content-type', 'application/vnd.oracle.adf.resourceitem+json');
                        xhr.setRequestHeader('Authorization', authorization);
                    },
                    data: JSON.stringify(payload),
                    dataType: 'json',
                    success: function (data) {
                        self.requestFailMsg('');
                        self.requestSuccessMsg('Request has been submitted successfully’);
                        self.name('');
                        self.email('');
                        self.phone('');
                        self.subject('');
                        self.message('');
                    },
                    error: function (jqXhr, textStatus, errorThrown) {
                        console.log('Error:');
                        console.log(jqXhr);
                        self.requestSuccessMsg('');
                        self.requestFailMsg('Failed to submit the request');
                    }
                });
            },
            'errorCallback': function (xhr, status, err) {
                if (xhr && xhr.status === 200) {
                    token = xhr.responseText;
                    console.log('Got token');
                } else {
                    console.error('getToken: xhr: ' + JSON.stringify(xhr) + ' status: ' + status + ' error: ' + err);
                    self.requestSuccessMsg('');
                    self.requestFailMsg('Failed to get authorization token');
                }
            }
        });
    };

Modify styles/design.css

Add the following css to design.css.

.form {
    font-family: "Helvetica Neue", "Segoe UI", sans-serif-regular, Helvetica, Arial, sans-serif;
    font-size: 14px;
}
.form input[type=text] {
    width: 100%;
    padding: 12px 20px;
    margin: 8px 0;
    display: inline-block;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}
.form textarea {
    width: 100%;
    padding: 12px 20px;
    margin: 8px 0;
    display: inline-block;
    border: 1px solid #ccc;
    border-radius: 4px;
    box-sizing: border-box;
}
.form button  {
    width: 100%;
    background-color: #4CAF50;
    color: white;
    padding: 14px 20px;
    margin: 8px 0;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
.form button:hover {
    background-color: #45a049;
}
.form button:disabled {
    background-color: #dddddd;
}
.required-field::after {
  content: "*";
  color: red;
  margin-left:2px
}
.request-msg {
	padding: 5px;
	font-size: 18px;
	font-weight: bold;
	text-align: center;
	margin-bottom: 20px;
}
.green {
	background-color: #81BA5E;
}
.red {
	background-color: red;
}

Use the Form Component on Oracle Content Management

  1. Configure the VBCS connection:

    • Choose Administration, then Integrations, and then Applications.

    • Click the Visual Builder Cloud Service Integration check box.

    • Enter the URL, and click Save.

  2. Import the component:

  3. Add the component to a page

    1. Edit a new or existing site.

    2. In Site Builder, choose Components and then Custom.


      Description of vbcs_components_custom.png follows
      Description of the illustration vbcs_components_custom.png
    3. Drag the component onto the page.

      Note:

      This VBCS secure form component works only on secure sites.