Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@andymarch
Last active March 16, 2023 03:12
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andymarch/560abdc9ea86d52030db0a2486c7c217 to your computer and use it in GitHub Desktop.
Save andymarch/560abdc9ea86d52030db0a2486c7c217 to your computer and use it in GitHub Desktop.
Okta Sign in widget snippets
var email = ""
config['registration'] = {
preSubmit: function (postData, onSuccess, onFailure) {
email = postData.email
onSuccess(postData);
},
postSubmit: async function (response, onSuccess, onFailure) {
// WARNING DEMO ONLY, NOT PRODUCTION
//these two calls should be moved to a backend-for-frontend where they can be called properly
// DO NOT PUT TOKENS IN YOUR FRONTEND CODE
const userLookUp = await fetch(
'https://account.examplydev.co.uk/api/v1/users/'+email,
{
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'SSWS <a token>'
}
});
const userLookupJSON = await userLookUp.json();
var payload = {
"factorType": "email",
"provider": "OKTA",
"profile": {
"email": email
}
}
const factorenroll = await fetch(
'https://account.examplydev.co.uk/api/v1/users/'+userLookupJSON.id+'/factors?activate=true',
{
method: 'POST',
body: JSON.stringify(payload),
headers: {
'Content-Type': 'application/json',
'Authorization': 'SSWS <a token>'
}
});
const myJson = await factorenroll.json();
onSuccess(response);
}
}
oktaSignIn.on('afterRender', function (context) {
if(context.controller === 'enroll-choices'){
//add logic validate that only one enrollment factor is available, else first will be chosen
var button = document.getElementsByClassName('select-factor')[0]
button.dispatchEvent(new Event('click', { 'bubbles': true }))
}
})
oktaSignIn.on('afterRender', function (context) {
console.log("currently showing: "+ context.controller)
}
<style>
.mfa-verify-passcode .o-form-fieldset-container{
display: flex !important;
flex-direction: column;
align-items: center;
}
.mfa-verify-passcode .auth-passcode{
order:2;
text-align: center
}
.mfa-verify-passcode .sms-request-button {
order:1;
}
</style>
oktaSignIn.on('ready', function (context) {
console.log(context.controller)
if(context.controller == "primary-auth" || context.controller == "refresh-auth-state"){
setTimeout(stateEngineExpired, 900000)
}
})
function stateEngineExpired(){
// monitor for input fields shows on screen depending if you have username or username and password change the fields
document.getElementById("okta-signin-username").addEventListener("change", refreshStateEngine);
document.getElementById("okta-signin-username").addEventListener("focus", refreshStateEngine);
document.getElementById("okta-signin-username").addEventListener("input", refreshStateEngine);
}
function refreshStateEngine(){
// redirect the user to the login init uri on the client application
// exactly how each app does this is changeable so could be varied based on the client id in the context
// for this example just move the user to the root of the redirect uri
var destination = new URL(context.authentication.request.redirect_uri)
window.location.replace(destination.origin)
}
oktaSignIn.on('afterRender', function (context) {
if(context.controller == "password-reset"){
var reqList = document.getElementsByClassName("password-requirements--list")[0].children[0]
var newReq = document.createElement("li")
newReq.setAttribute("class", "password-requirements--list-item")
const newContent = document.createTextNode("Not a common password according to custom list");
newReq.appendChild(newContent);
reqList.appendChild(newReq)
var passwordField = document.getElementsByClassName("o-form-input-name-newPassword")[0].children[0]
passwordField.setAttribute("onblur", "checkPasswords()")
var submitButton = document.getElementsByClassName("button-primary")[0]
submitButton.setAttribute("disabled",true)
}
})
function checkPasswords(){
//reset UI
var container = document.getElementsByClassName('o-form-error-container')[0]
if(container.classList.contains("o-form-has-errors")){
container.classList.remove("o-form-has-errors");
container.removeChild(container.children[0])
}
var submitButton = document.getElementsByClassName("button-primary")[0]
submitButton.setAttribute("disabled",true)
var allow = false
var passwordField = document.getElementsByClassName("o-form-input-name-newPassword")[0].children[0]
if(passwordField.value.length>0){
//your logic, check haveibeenpwned, custom list etc
allow = passwordField.value != "Password!"
if(allow){
submitButton.removeAttribute("disabled")
}
else{
var div = document.createElement('div');
div.innerHTML = `
<div class="okta-form-infobox-error infobox infobox-error" role="alert"><span class="icon error-16"></span><p>This password was found in a custom list of restricted passwords. Please try another password.</p></div>
`;
var container = document.getElementsByClassName('o-form-error-container')[0]
container.appendChild(div);
container.classList.add("o-form-has-errors");
}
}
}
oktaSignIn.on('afterRender', function (context) {
if (context.controller == 'forgot-password') {
var reset = document.getElementsByClassName('button-primary')[0];
reset.addEventListener('click', function (e) {
var textfield = document.getElementById('account-recovery-username')
console.log(textfield.value)
e.preventDefault();
e.stopPropagation();
});
}
})
oktaSignIn.on('ready', function (context) {
if(context.controller == "registration"){
let params = (new URL(document.location)).searchParams;
if(params.get("username")) {
var username = decodeURIComponent(params.get("username"));
var usernameInput = document.getElementById("input3")
usernameInput.value = username;
usernameInput.readOnly = true;
usernameInput.dispatchEvent(new Event('change', { 'bubbles': true }))
}
}
}
<script type="text/javascript">
// "config" object contains default widget configuration
// with any custom overrides defined in your admin settings.
var config = OktaUtil.getSignInWidgetConfig();
//if we have context let customize the experiance
var context = OktaUtil.getRequestContext()
if(context){
if(context.target.clientId === '0oa5szrt7X3F2WBZR0x6'){
//change any config elements per clientid
config["i18n"] = {
en: {
'primaryauth.title': 'Sign in to Acme'
}
}
//Add custom CSS
var head = document.head;
var link = document.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = 'https://example.com/styles/' + context.target.clientId + '.css';
head.appendChild(link);
}
}
// Render the Okta Sign-In Widget
var oktaSignIn = new OktaSignIn(config);
oktaSignIn.renderEl({ el: '#okta-login-container' },
OktaUtil.completeLogin,
function(error) {
// Logs errors that occur when configuring the widget.
// Remove or replace this with your own custom error handler.
console.log(error.message, error);
}
);
</script>
//Unhide the checkbox element
<style>
input[type="checkbox"]{
position:revert;
opacity: 1;
position: revert;
width: revert;
height: revert;
}
</style>
config["registration"] = {
preSubmit: function (postData, onSuccess, onFailure) {
postData.tc_accept = document.getElementById("tcAccept").checked
}
}
//Looks for the registration page then run prettyCheckBoxes
oktaSignIn.on('afterRender', function (context) {
if (context.controller == 'registration') {
prettyCheckBoxes()
return;
}
});
//hide the ugly select and inject a proper check element
function prettyCheckBoxes() {
if (document.getElementsByClassName("o-form-input-name-tc_accept")[0].children.length < 2) {
window.requestAnimationFrame(prettyCheckBoxes);
} else {
document.getElementsByClassName("o-form-input-name-tc_accept")[0].children[1].style.display = "none"
var x = document.createElement("DIV")
var checkBox = document.createElement("INPUT")
checkBox.setAttribute("type", "checkbox")
checkBox.setAttribute("id","tcAccept")
checkBox.setAttribute("name","tcAccept")
x.appendChild(checkBox)
var label = document.createElement("label")
var t = document.createTextNode("I accept the terms and conditions");
label.setAttribute("for","tcAccept")
label.appendChild(t)
x.appendChild(label)
document.getElementsByClassName("o-form-input-name-tc_accept")[0].appendChild(x);
}};
var signIn = new OktaSignIn(
{
baseUrl: 'https://{yourOktaDomain}',
redirectUri: '{{redirectUri configured in OIDC app}}',
authParams: {
display: 'page',
pkce: true
},
registration: {
parseSchema: function(schema, onSuccess, onFailure) {
schema.profileSchema.properties.email = {
'type': 'string',
'title': 'Login'
};
onSuccess(schema);
},
preSubmit: function (postData, onSuccess, onFailure) {
//injects '@example' to fulfil the requirement for email formatted
//value for the the email attribute as this is reused for primary_email
if (postData.email.indexOf('@') > 1) {
console.log("email")
onSuccess(postData)
} else {
postData.email = postData.email + "@example.com";
console.log(postData)
onSuccess(postData)
}
}
},
features: {
registration: true // REQUIRED
}
}
);
@RakeshNomula
Copy link

Hi,

I am trying to update okta widget username dynamically. In the above code, Is OktaUtil is an external library?
I am not able to download the zip file to verify in the codebase.
Could you please help

@andymarch
Copy link
Author

OktaUtil is available when running the hosted sign in experience.
I you just want to set the user name you can pass username: in the config that creates the widget see the documentation here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment