@quandis/qbo4.security
v4.0.1-CI-20251219-230238
Published
Provides web-based authentication controls and API endpoints for managing accounts and security-related features such as token generation, access keys, and IP address restrictions.
Downloads
1,145
Keywords
Readme
Security Management
Provides web-based authentication controls and API endpoints for managing accounts and security-related features such as token generation, access keys, and IP address restrictions.
API Samples
POST /security/account/token
Use this method to obtain a JavaScript Web Token.
using System.Net.Http.Json;
var http = new HttpClient
{
BaseAddress = new Uri("https://your-api-host")
};
var tokenRequest = new TokenRequest
{
AccessKey = "your-access-key",
SecretKey = "your-secret-key"
};
var response = await http.PostAsJsonAsync("/security/account/token", tokenRequest);
response.EnsureSuccessStatusCode();
var token = await response.Content.ReadFromJsonAsync<TokenResponse>();
Console.WriteLine($"Access Token: {token?.AccessToken}");
Console.WriteLine($"Token Type: {token?.TokenType}");
Console.WriteLine($"Expires In (seconds): {token?.ExpiresInSeconds}");curl -X POST "https://your-api-host/security/account/token" \
-H "Content-Type: application/json" \
-d '{
"accessKey": "your-access-key",
"secretKey": "your-secret-key"
}'Web Controls
The following web controls are provided for authentication and security flows.
Sign-In Control
<qbo-login> — Login + 2FA + SSO + License flow.
A Lit-based web component that implements a full authentication funnel:
- Username/password sign-in.
- Optional two-factor (SMS/Email/Authenticator) via
<qbo-2fa>. - Optional license acceptance gate.
- Password change/reset/invite confirmations via
<qbo-password>/<qbo-invite>. - Pluggable SSO (“OIDC”) buttons.
- Slot-based theming and header/footer overrides.
Quick start
<script type="module" src="/path/to/qbo-login.js"></script>
<qbo-login
pathbase="/auth/" <!-- every API call is relative to this -->
allowedSSOLoginList="Google,Okta" <!-- restrict SSO buttons -->
shouldfollowreturnurl="true" <!-- follow ReturnUrl after sign-in -->
enableauthenticator="true" <!-- show authenticator option in 2FA -->
>
<!-- Optional styling injected into the shadow DOM -->
<style slot="login-styles">
/* Your custom CSS */
</style>
<!-- Optional: replace the default header -->
<div slot="login-form-header">
<qbo-form-header heading="Welcome back" subheading="Sign in to continue"></qbo-form-header>
</div>
</qbo-login>By default, the component renders inside a shadow root. Set lightdom to true if you prefer light DOM.
Server endpoints (expected)
All endpoints are built from pathbase (e.g., /auth/):
- POST {base}signin – main login.
- Response (subset):.
{
"succeeded": true,
"requiresTwoFactor": false,
"licenseAcceptEndpoint": "",
"legacyPasswordWeak": false,
"ipValidationFailed": false,
"changePasswordRequired": false,
"isLockedOut": false,
"isNotAllowed": false,
"phoneRequired": false,
"emailConfirmation": false,
"returnUrl": "/",
"twoFactorMethods": [
{ "methodType": "Email", "value": "[email protected]" },
{ "methodType": "Phone", "value": "+1 (*** ) ***-1234" },
{ "methodType": "Authenticator", "value": "enabled|disabled" }
],
"exception": null
}GET {base}oidc– SSO providers.- Response:
[{ displayName, authenticationScheme, imagePath? }, ...].
- Response:
GET {base}license– fetch license content.- Response:
{ html?: string, text?: string, date: string }.
- Response:
POST {base}license– accept license (expects 200 and body containing “accepted”)GET {base}signout– log out Two-factor (SMS/Email/Auth) & phone add/change are handled inside using additional endpoints (e.g., twofa/sms, phone/add, etc.).
Attributes / Properties
|Name|Type|Default|Description|
|-|-|-|-|
|pathbase|string|undefined|Base path for all API calls|
|allowedSSOLoginList|string|""|Comma-separated list of allowed SSO schemes (case-insensitive. If empty, no SSO buttons render.|
|renderLogout|boolean|false|If true, renders a Logout button|
|lightdom|boolean|false|If true, renders in light DOM|
|enableauthenticator|string|"true"|Enables offering the Authenticator method in 2FA. Use "false" to disable|
|shouldfollowreturnurl|string|"true"|if "true", navigates to ReturnUrl after success. If "false", navigates to current URL.|
|licenseContent|object|null|Optional preloaded license content; if omitted, component fetches it when needed.|
Internal state (read-only for consumers):
- loginState:
'default' | 'twoFactor' | 'lockedOut' | 'notAllowed' | 'license' | 'register' | 'changePasswordRequired' | 'passwordWeak' | 'reset' | 'resetEmail' | 'phoneRequired' | 'invite' | 'licenseAcceptEndpoint' | 'emailConfirmation' | 'phoneChange' | 'ipFailed' | 'error' | 'success'
Slots
These slots let you customize headers, styles, parts of the flow. Anything not provided falls back to defaults.
|Slot name|Used in view|Purpose|
|-|-|-|
|login-styles|Login|Style elements in injected into the shadow root for the login view|
|login-form-header|Login|Replace the login header|
|login-form|Login|Replace the entire login form|
|form-footer|Login|Replace the login footer (buttons).|
|divider|Login|Replace the "or" divider|
|oidc-buttons|Login|Replace the SSO buttons container|
|login-password-reset-form|Login|Replace the "Forgot password?" link block|
|login-register-form|Login|Replace the "Register" link block|
|mfa-form-header|2FA/Email/Phone/Register|Header shown in <qbo-2fa> and registration MFA subflows|
|mfa-styles|2FA/Email/Phone/Register|Style elements injected into <qbo-2fa> shadow root.|
|password-form-header|Password update/reset/2FA|Header for password flows rendered via <qbo-password>|
|password-styles|Password update/reset/2FA|Styles injected into <qbo-password>|
|password-change-form-header|Password change required|Header specific to forced password change.|
|invite-form-header|Invite confirmation|Header for <qbo-invite>.|
|invite-styles|Invite confirmation|Styles injected into <qbo-invite>.|
For 2FA and password flows, headers/styles are forwarded to child components by cloning the slotted nodes.
Navigation and Return URL
- On initial load, the component reads
ReturnUrl/returnUrlfrom the page query string and stores it internally. - After successful auth:
- If
shouldfollowreturnurl="true"(default), navigate toReturnUrlor/. - If
shouldfollowreturnurl="false", navigate to current location instead.
- If
SSO ("OIDC") buttons
- On connect, the component calls
GET {base}odic. - You can restrict what to show via
allowedSSOLoginList="Google,Okta". - Each provider may supply a custom
imagePath. If omitted, the component builds a default icon URL usinggetImageBasePath()and${displayName.toLowerCase()}-icon.svg.
Clicking an SSO button redirects to
{base}oidc/login/{authenticationScheme}?ReturnUrl=<encoded>Two-factor authentication (2FA)
When POST /signin returns requiresTwoFactor:true, the component enters the twoFactor state and renders <qbo-2fa> with:
email,phoneNumberand (optionally)authenticatormethod population.enableAuthenticatorforwarded so you can disable the authenticator option globally.- The same
pathbase,shouldfollowreturnurl, andreturnurl. If the backend returnslicenseAcceptEndpointafter 2FA sign-in,<qbo-2fa>dispatches a license-required event.<qbo-login>listens for this and switches to the license view.
License gate
License can be triggered either:
- Directly after
POST /signin(whenlicenseAcceptEndpointis present) or - Emitted by child flows via a
license-requiredcustom event (eg., after 2FA sign-in).
The component fetches license content with GET {base}license, then renders an accept view. Accepting POSTS to {base}license and navigates on success.
You can also preload content by setting the licenseContent property.
Password flows
- Weak legacy password →
passwordWeakstate →<qbo-password isReset="true"> - Change required →
changePasswordRequired→<qbo-password isPasswordChange="true"> - Forgot password? →
resetEmail→<qbo-password isReset="true"> - Direct reset link →
reststate (passwordReset=true&userid=...&token=...present)
All header/styles slots for password flows are forwarded to <qbo-password>
Invite confirmation
If the query string includes ?registerConfirm=true&userid=...&token=..., the component enters the invite state and renders <qbo-invite>, passing userId / token. The invite component performs confirmation, then redirects as needed.
Error states
lockedOut/notAllowed/ipFailedshow "contact support" with a link back to login.- Any non-OK responses with
exception=>errorstate with an error message. - Inline status messages are rendered via
renderDismissibleStatus.
Styling
- Base CSS:
qbocss+securityCss - Provide
<style slot="login-styles">to inject additional styles into the login shadow root. - Provide
<style slot="mfa-styles">etc.. for subflows.
If you must style from the outside, set lightdom="true".
Events listened and propagated
- Listened: license-required (bubbles/composed). When received, the component fetches and shows the license agreement.
- Propagated: Subcomponents (2FA/password/invite) handle their own events internally and redirect according to the same naviation rules.
Examples
- Disable authenticator method and restrict to Okta SSO
<qbo-login
pathbase="/auth/"
enableauthenticator="false"
allowedSSOLoginList="Okta"
></qbo-login>- Light DOM (for global CSS) with custom footer
<qbo-login lightdom pathbase="/auth/">
<div slot="form-footer">
<div class="actions">
<button type="submit" class="qbo-base-button">Sign in</button>
<a href="/help" class="qbo-link">Need help?</a>
</div>
</div>
</qbo-login>- Supply custom MFA and password styles/headers
<qbo-login pathbase="/auth/">
<style slot="mfa-styles">
.qbo-mfa-form { max-width: 480px; }
</style>
<div slot="mfa-form-header">
<qbo-form-header heading="Two-factor" subheading="Enter the code to continue"></qbo-form-header>
</div>
<style slot="password-styles">
.qbo-password-form { max-width: 480px; }
</style>
<div slot="password-form-header">
<qbo-form-header heading="Update password" subheading="Please choose a stronger password"></qbo-form-header>
</div>
</qbo-login>Access Key Control
This is where the access key control documentation would go.
IP Address Control
This is where the IP address control documentation would go.
