@quandis/qbo4.security 4.0.1-CI-20250604-212147
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +47 -0
- package/readme.md +264 -0
- package/scss/qbo-security.scss +173 -0
- package/src/Program.d.ts +9 -0
- package/src/Program.js +10 -0
- package/src/Program.js.map +1 -0
- package/src/Program.ts +11 -0
- package/src/qbo-2fa.d.ts +40 -0
- package/src/qbo-2fa.js +604 -0
- package/src/qbo-2fa.js.map +1 -0
- package/src/qbo-2fa.ts +558 -0
- package/src/qbo-form-header.d.ts +7 -0
- package/src/qbo-form-header.js +47 -0
- package/src/qbo-form-header.js.map +1 -0
- package/src/qbo-form-header.ts +31 -0
- package/src/qbo-invite.d.ts +42 -0
- package/src/qbo-invite.js +532 -0
- package/src/qbo-invite.js.map +1 -0
- package/src/qbo-invite.ts +521 -0
- package/src/qbo-login.d.ts +45 -0
- package/src/qbo-login.js +525 -0
- package/src/qbo-login.js.map +1 -0
- package/src/qbo-login.ts +532 -0
- package/src/qbo-navbar.d.ts +5 -0
- package/src/qbo-navbar.js +28 -0
- package/src/qbo-navbar.js.map +1 -0
- package/src/qbo-navbar.ts +21 -0
- package/src/qbo-password.d.ts +21 -0
- package/src/qbo-password.js +309 -0
- package/src/qbo-password.js.map +1 -0
- package/src/qbo-password.ts +278 -0
- package/src/qbo-register.d.ts +22 -0
- package/src/qbo-register.js +278 -0
- package/src/qbo-register.js.map +1 -0
- package/src/qbo-register.ts +248 -0
- package/src/qbo-utils.d.ts +2 -0
- package/src/qbo-utils.js +22 -0
- package/src/qbo-utils.js.map +1 -0
- package/src/qbo-utils.ts +18 -0
- package/src/styles.d.ts +1 -0
- package/src/styles.js +3 -0
- package/src/styles.js.map +1 -0
- package/src/styles.ts +3 -0
- package/wwwroot/css/qbo-security.css +157 -0
- package/wwwroot/css/qbo-security.css.map +1 -0
- package/wwwroot/css/qbo-security.min.css +1 -0
- package/wwwroot/js/esm/qbo4.security.js +5673 -0
- package/wwwroot/js/esm/qbo4.security.min.js +127 -0
- package/wwwroot/js/esm/qbo4.security.min.js.map +1 -0
- package/wwwroot/js/qbo4.configuration.js +42 -0
- package/wwwroot/js/qbo4.configuration.min.js +2 -0
- package/wwwroot/js/qbo4.configuration.min.js.LICENSE.txt +14 -0
- package/wwwroot/js/qbo4.configuration.min.js.map +1 -0
- package/wwwroot/js/qbo4.security.js +17331 -0
- package/wwwroot/js/qbo4.security.min.js +1233 -0
- package/wwwroot/js/qbo4.security.min.js.LICENSE.txt +47 -0
- package/wwwroot/js/qbo4.security.min.js.map +1 -0
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@quandis/qbo4.security",
|
|
3
|
+
"version": "4.0.1-CI-20250604-212147",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"types": "./src/Program.d.ts",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"import": "./src/Program.js"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"wwwroot/js/",
|
|
13
|
+
"wwwroot/css/",
|
|
14
|
+
"src/",
|
|
15
|
+
"scss/"
|
|
16
|
+
],
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@quandis/qbo4.ui": "^4.0.1-CI-20250523-132334",
|
|
19
|
+
"@vaadin/router": "^2.0.0",
|
|
20
|
+
"bootstrap": "^5.3.6",
|
|
21
|
+
"lit": "^3.3.0",
|
|
22
|
+
"reflect-metadata": "^0.2.2",
|
|
23
|
+
"ts-loader": "^9.5.2",
|
|
24
|
+
"tsyringe": "^4.10.0"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"@fullhuman/postcss-purgecss": "^7.0.2",
|
|
28
|
+
"autoprefixer": "^10.4.21",
|
|
29
|
+
"clean-css": "^5.3.3",
|
|
30
|
+
"eslint": "^9.27.0",
|
|
31
|
+
"glob": "^11.0.2",
|
|
32
|
+
"mini-css-extract-plugin": "^2.9.2",
|
|
33
|
+
"postcss-cli": "^11.0.1",
|
|
34
|
+
"postcss-loader": "^8.1.1",
|
|
35
|
+
"sass": "^1.89.0",
|
|
36
|
+
"typescript": "^5.8.3",
|
|
37
|
+
"webpack": "^5.99.9",
|
|
38
|
+
"webpack-cli": "^6.0.1",
|
|
39
|
+
"webpack-merge": "^6.0.1"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"sass": "sass --load-path=node_modules --quiet scss/:wwwroot/css && node cssshake.js",
|
|
43
|
+
"packdev": "webpack --config webpack.dev.js --no-color",
|
|
44
|
+
"packprod": "webpack --config webpack.prod.js --no-color",
|
|
45
|
+
"build": "ncu -u && npm install && npm run sass && tsc --build --force && npm run packdev && npm run packprod && del *.tgz && npm pack && ren *.tgz qbo4.security.tgz"
|
|
46
|
+
}
|
|
47
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Overview
|
|
2
|
+
|
|
3
|
+
The `@quandis/qbo4.Configuration.Web` package offers:
|
|
4
|
+
|
|
5
|
+
- Management of options classes via dependency injection
|
|
6
|
+
- A `QboTemplate` web component base class that supports configuration driven rendering options
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Options Classes
|
|
10
|
+
|
|
11
|
+
Similar to Microsoft's `IConfiguration`, the `qbo4.Configuration` package's classes manage configuration settings
|
|
12
|
+
for a web application via dependency injection.
|
|
13
|
+
|
|
14
|
+
Including the `qbo4.Configuration.js` script will provide:
|
|
15
|
+
|
|
16
|
+
`qbo4.services`: a container for dependency injection (including `qbo4.services.container` for direct access to the `tsyringe` container)
|
|
17
|
+
`qbo4.configuration`: a set of classes to manage configuration settings
|
|
18
|
+
`IConfiguration`: an interface to manage configuration settings
|
|
19
|
+
|
|
20
|
+
It provides for dependency injections via the `tsyringe` package.
|
|
21
|
+
|
|
22
|
+
## Typescript Usage
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import 'reflect-metadata';
|
|
26
|
+
import { Configuration, IConfiguration, IConfigurationSource, IConfigurationSourceToken, IConfigurationToken, JsonConfigurationSource, services } from '@quandis/qbo4.configuration';
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class OptionsA { public name: string = ''; }
|
|
30
|
+
class OptionsB { public count: number = 0; }
|
|
31
|
+
|
|
32
|
+
const source1 = new JsonConfigurationSource({ A: { name: 'Alice' }, B: { count: 27 } });
|
|
33
|
+
const source2 = new JsonConfigurationSource({ A: { name: 'Bob' }, C: { enabled: true } });
|
|
34
|
+
services.container.register<IConfigurationSource>(IConfigurationSourceToken, { useValue: source1 });
|
|
35
|
+
services.container.register<IConfigurationSource>(IConfigurationSourceToken, { useValue: source2 });
|
|
36
|
+
|
|
37
|
+
const config: IConfiguration = services.container.resolve<IConfiguration>(IConfigurationToken);
|
|
38
|
+
expect(config).not.null;
|
|
39
|
+
const a = config.getSection('A').bind(OptionsA);
|
|
40
|
+
expect(a.name).equal('Bob');
|
|
41
|
+
|
|
42
|
+
const b = config.getSection('B').bind(OptionsB);
|
|
43
|
+
expect(b.count).equal(27);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Browser Usage
|
|
47
|
+
|
|
48
|
+
```html
|
|
49
|
+
<html>
|
|
50
|
+
<head>
|
|
51
|
+
<script src="//configuration/js/qbo4.Configuration.js"></script>
|
|
52
|
+
<script type="text/javascript">
|
|
53
|
+
const aiConfig = new qbo4.logging.JsonConfigurationSource({ 'ApplicationInsights': { instrumentationKey: '651cc99f-0b30-4f27-8918-e53dfed1a2c2' } });
|
|
54
|
+
qbo4.services.container.register(qbo4.logging.IConfigurationSourceToken, { useValue: aiConfig });
|
|
55
|
+
// now the configuration settings are available for dependency injection
|
|
56
|
+
|
|
57
|
+
// later in your code, web components, or scripts:
|
|
58
|
+
const instances = qbo4.services.container.resolveAll<SomeInterface>(SomeInterfaceToken);
|
|
59
|
+
|
|
60
|
+
</script>
|
|
61
|
+
</head>
|
|
62
|
+
<body>
|
|
63
|
+
</body>
|
|
64
|
+
</html>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Example: ApplicationInsights Logger
|
|
68
|
+
|
|
69
|
+
Assume we want to inject an `ApplicationInsights` logger, where the `InstrumentationKey` is stored in the configuration settings.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// An options class
|
|
73
|
+
export class ApplicationInsightsOptions {
|
|
74
|
+
public InstrumentationKey: string = '';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Prepare the options for dependency injection (a tsyring pattern)
|
|
78
|
+
export const ApplicationInsightsOptionsToken: InjectionToken<ApplicationInsightsOptions> = 'ApplicationInsightsOptions';
|
|
79
|
+
|
|
80
|
+
// The logger class
|
|
81
|
+
@injectable()
|
|
82
|
+
export class ApplicationInsights {
|
|
83
|
+
constructor(
|
|
84
|
+
@inject(ApplicationInsightsOptionsToken) private options: ApplicationInsightsOptions
|
|
85
|
+
) {
|
|
86
|
+
// Initialize the logger
|
|
87
|
+
// ...
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Prepare the class for dependency injection
|
|
92
|
+
export const ApplicationInsightsToken: InjectionToken<ApplicationInsights> = 'ApplicationInsights';
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
# QboTemplate Web Component
|
|
96
|
+
|
|
97
|
+
The `QboTemplate` web component enables power users to configure the rendering of a web component a runtime.
|
|
98
|
+
Assume we have a `Contact` web component that renders a contact's name, address, and other information,
|
|
99
|
+
and we choose to support different layouts based on a `type` attribute:
|
|
100
|
+
|
|
101
|
+
```html
|
|
102
|
+
<qbo-contact type="fullname"></qbo-contact>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
should render:
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<input name="first" placeholder="First name"/>
|
|
109
|
+
<input name="middle" placeholder="Middle name"/>
|
|
110
|
+
<input name="last" placeholder="Last name"/>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Such a web component might look like this:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { html } from 'lit';
|
|
117
|
+
import { customElement } from 'lit/decorators.js';
|
|
118
|
+
|
|
119
|
+
@customElement('qbo-contact')
|
|
120
|
+
export class ContactComponent extends LitElement {
|
|
121
|
+
jsonData: object = {
|
|
122
|
+
'Contact': {
|
|
123
|
+
'First': 'James',
|
|
124
|
+
'Middle': 'Tiberious',
|
|
125
|
+
'Last': 'Kirk'
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
render() {
|
|
130
|
+
return html`
|
|
131
|
+
<input name="first" placeholder="First name" value="${this.jsonData['Contact']['First']}"/>
|
|
132
|
+
<input name="middle" placeholder="Middle name" value="${this.jsonData['Contact']['Middle']}"/>
|
|
133
|
+
<input name="last" placeholder="Last name" value="${this.jsonData['Contact']['Last']}"/>
|
|
134
|
+
`;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Futher assume that you want to allow a power user to configure the layout of the `qbo-contact` web component at runtime.
|
|
140
|
+
To accomplish this, shift the `ContactComponent` to derive from a `QboTemplate` class:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import { html } from 'lit';
|
|
144
|
+
import { customElement } from 'lit/decorators.js';
|
|
145
|
+
import { templates, TemplateFunction, QboTemplate } from '@quandis/qbo4.configuration';
|
|
146
|
+
|
|
147
|
+
export class ContactComponent extends QboTemplate {
|
|
148
|
+
constructor() {
|
|
149
|
+
super();
|
|
150
|
+
this.type ??= 'default';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
jsonData: object = {
|
|
154
|
+
'Contact': {
|
|
155
|
+
'First': 'James',
|
|
156
|
+
'Middle': 'Tiberious',
|
|
157
|
+
'Last': 'Kirk'
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Notice: no render method here - see below.
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const contactTemplates = new Map<string, TemplateFunction>();
|
|
165
|
+
|
|
166
|
+
contactTemplates.set('default', (component: any) => {
|
|
167
|
+
return html`<input name="first" placeholder="First name" value="${component.jsonData['Contact']['First']}"/>
|
|
168
|
+
<input name="middle" placeholder="Middle name" value="${component.jsonData['Contact']['Middle']}"/>
|
|
169
|
+
<input name="last" placeholder="Last name" value="${component.jsonData['Contact']['Last']}"/>`;
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
contactTemplates.set('reverse', (component: any) => {
|
|
173
|
+
return html`<input name="last" placeholder="Last name" value="${component.jsonData['Contact']['First']}"/>,
|
|
174
|
+
<input name="first" placeholder="Last name" value="${component.jsonData['Contact']['Last']}"/>
|
|
175
|
+
<input name="middle" placeholder="Middle name" value="${component.jsonData['Contact']['Middle']}"/>`
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// template is a global variable set by the qbo4.configuration package
|
|
179
|
+
templates.set('ContactComponent', contactTemplates);
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Now you can render the `qbo-contact` web component with a `type` attribute:
|
|
183
|
+
|
|
184
|
+
```html
|
|
185
|
+
<!-- This will render last name, first name, middle name -->
|
|
186
|
+
<qbo-contact type="reverse"></qbo-contact>
|
|
187
|
+
|
|
188
|
+
<!-- This will render first name, middle name, last name -->
|
|
189
|
+
<qbo-contact type="default"></qbo-contact>
|
|
190
|
+
|
|
191
|
+
<!-- So will this, because we set type = 'default' in the constructor -->
|
|
192
|
+
<qbo-contact></qbo-contact>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
> Note that the template functions accept a `component` parameter, which is the instance of the `ContactComponent` class.
|
|
196
|
+
Ensure you reference your component's properties via `component` rather than `this`.
|
|
197
|
+
|
|
198
|
+
Mapping `type` to different rendering functions is all well and good, but not particularly interesting.
|
|
199
|
+
|
|
200
|
+
The interesting part is allowing a power user to create new rendering functions (or edit existing ones) at runtime.
|
|
201
|
+
|
|
202
|
+
The `QboTemplate` class will listen for a `ctrl-dblclick` event if it is contained in an element with a `qbo-design` class
|
|
203
|
+
(indicating that we are in 'design' mode).
|
|
204
|
+
|
|
205
|
+
When the `ctrl-dblclick` event is triggered, a dialog will open, presenting the user with something like:
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
**Edit Template**
|
|
209
|
+
|
|
210
|
+
[ default ↓ ] <- *a datalist of available templates*
|
|
211
|
+
|
|
212
|
+
```html
|
|
213
|
+
1 <input name="first" placeholder="First name" value="${component.jsonData.Contact.First]}"/>
|
|
214
|
+
2 <input name="middle" placeholder="Middle name" value="${component.jsonData.Contact.Middle]}"/>
|
|
215
|
+
3 <input name="last" placeholder="Last name" value="${component.jsonData.Contact.Last}"/>
|
|
216
|
+
```
|
|
217
|
+
^ *an editor for editing the rendering function*
|
|
218
|
+
|
|
219
|
+
[ *Ask AI to code...* ]
|
|
220
|
+
|
|
221
|
+
[ Save ] [ Cancel ]
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
Feature include:
|
|
226
|
+
|
|
227
|
+
- As the power user modifies the template, the underlying UI will update in real-time.
|
|
228
|
+
- Any syntax errors will be trapped and displayed in the editor
|
|
229
|
+
- The editor can be dragged and resized as needed
|
|
230
|
+
- The `type` at the top can be selected from a `datalist`, and new types can be entered.
|
|
231
|
+
- The `Ask AI to code...` input will apply Generative AI to modify the code as you describe.
|
|
232
|
+
- Clicking `Save` will save the template in configuration (server-side), and be available for use.
|
|
233
|
+
- Clicking `Cancel` will discard any changes, reverting to the original rendering.
|
|
234
|
+
|
|
235
|
+
## How it Works
|
|
236
|
+
|
|
237
|
+
Deployment of `@qbo4.Configuration` web components is paired with deployment of the `qbo4.Configuration.Web` Razor Class Library,
|
|
238
|
+
which includes server-side functionality to store are retrieve template code.
|
|
239
|
+
The `QboTemplate` class will interact with the server-side `/template` endpoint to store and retrieve templates.
|
|
240
|
+
|
|
241
|
+
The `QboTemplate` class will render the web component based on the `type` attribute, using the `templates` map.
|
|
242
|
+
If the `type` is not found in the `templates` map, the component will `fetch` templates stored in configuration
|
|
243
|
+
from the `/template/search/{ComponentClassName}` endpoint.
|
|
244
|
+
|
|
245
|
+
> If a component's `Typescript` class defines a `type` that also exists in configuration, the configuration will take precedence.
|
|
246
|
+
|
|
247
|
+
## Spiderman Clause
|
|
248
|
+
|
|
249
|
+
With great power comes great responsibility. Only trusted user should be allowed to edit templates.
|
|
250
|
+
The ultimate control of this remains server-side with the authorization policies of the `/template` endpoints.
|
|
251
|
+
For the front-end, the `QboTemplate` class will only allow editing of templates if the containing element has a `qbo-design` class.
|
|
252
|
+
We recommend that the `qbo-design` class be added to the `body` for trusted power users only.
|
|
253
|
+
This will prevent accidental editing attempts of templates by regular users.
|
|
254
|
+
|
|
255
|
+
As with all qbo-based configuration, enable and test in a lower environment before deploying to production.
|
|
256
|
+
|
|
257
|
+
# RoadMap
|
|
258
|
+
|
|
259
|
+
- add intellisense to CodeMirror for component-specific properties (including Json data)
|
|
260
|
+
- shift the Editor to a separate web component
|
|
261
|
+
- enable custom Editors, to simplify changes to complex controls
|
|
262
|
+
- create a GUI designer that detects available web components via DI
|
|
263
|
+
- propagate changes to a components `type` property to parent components
|
|
264
|
+
- if a user creates a new `type` of an address control called `streetview`, and the address control is part of a property control, save the property control such that it uses `<qbo-address type="streetview">`
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/*@import "../node_modules/bootstrap/dist/css/bootstrap";*/
|
|
2
|
+
|
|
3
|
+
.custom-style {
|
|
4
|
+
display: flex;
|
|
5
|
+
justify-content: center;
|
|
6
|
+
align-items: center;
|
|
7
|
+
min-height: 100vh;
|
|
8
|
+
font-family: var(--qbo-font, Arial, sans-serif);
|
|
9
|
+
background-color: #f5f5f5;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/*form {
|
|
13
|
+
background: var(--qbo-background-color, white);
|
|
14
|
+
border: 1px solid var(--qbo-border-color, #e0e0e0);
|
|
15
|
+
padding: 2rem;
|
|
16
|
+
border-radius: var(--qbo-border-radius, 12px);
|
|
17
|
+
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
|
|
18
|
+
width: 100%;
|
|
19
|
+
max-width: 500px;
|
|
20
|
+
}*/
|
|
21
|
+
|
|
22
|
+
label {
|
|
23
|
+
display: block;
|
|
24
|
+
margin-bottom: var(--qbo-label-margin-bottom, 0.5rem);
|
|
25
|
+
font-weight: 600;
|
|
26
|
+
font-size: 0.95rem;
|
|
27
|
+
color: var(--qbo-color, #333);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
input {
|
|
31
|
+
display: block;
|
|
32
|
+
margin-bottom: var(--qbo-margin-vertical, 1rem);
|
|
33
|
+
width: 100%;
|
|
34
|
+
padding: var(--qbo-padding, 0.65rem 0.75rem);
|
|
35
|
+
border: 1px solid var(--qbo-border-color, #ccc);
|
|
36
|
+
border-radius: var(--qbo-border-radius, 8px);
|
|
37
|
+
font-size: 1rem;
|
|
38
|
+
transition: border-color 0.2s;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
input:focus {
|
|
42
|
+
border-color: var(--qbo-focus-border-color, #007bff);
|
|
43
|
+
outline: none;
|
|
44
|
+
box-shadow: 0 0 0 0.2rem var(--qbo-focus-box-shadow, rgba(0, 123, 255, 0.25));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
button {
|
|
48
|
+
width: 100%;
|
|
49
|
+
padding: var(--qbo-button-padding, 0.75rem);
|
|
50
|
+
background-color: var(--qbo-button-bg, var(--qbo-primary-bg, #007bff));
|
|
51
|
+
color: var(--qbo-button-color, var(--qbo-primary-color, #fff));
|
|
52
|
+
font-weight: bold;
|
|
53
|
+
font-size: 1rem;
|
|
54
|
+
border: 1px solid var(--qbo-button-border, var(--qbo-primary-border, #007bff));
|
|
55
|
+
border-radius: var(--qbo-button-border-radius, 8px);
|
|
56
|
+
cursor: pointer;
|
|
57
|
+
transition: background-color 0.2s, border-color 0.2s;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
button:hover:not(:disabled) {
|
|
61
|
+
background-color: var(--qbo-button-bg-hover, var(--qbo-primary-hover-bg, #0056b3));
|
|
62
|
+
border-color: var(--qbo-button-border-hover, var(--qbo-primary-hover-border, #004085));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
button:disabled {
|
|
66
|
+
opacity: 0.6;
|
|
67
|
+
cursor: not-allowed;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.qbo-row {
|
|
71
|
+
display: flex;
|
|
72
|
+
flex-direction: row;
|
|
73
|
+
/* align-items: flex-start;
|
|
74
|
+
flex-wrap: wrap;*/
|
|
75
|
+
}
|
|
76
|
+
.qbo-gap-xl {
|
|
77
|
+
column-gap: 3rem;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.qbo-form .form-check {
|
|
81
|
+
display: flex;
|
|
82
|
+
align-items: center;
|
|
83
|
+
gap: 0.5rem; /* space between checkbox and text */
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.qbo-form .form-check input[type="checkbox"],
|
|
87
|
+
.qbo-form .form-check input[type="radio"] {
|
|
88
|
+
width: auto;
|
|
89
|
+
margin: 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.qbo-form .form-check label {
|
|
93
|
+
margin-bottom: 0;
|
|
94
|
+
font-weight: 400;
|
|
95
|
+
color: var(--qbo-color);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.form-container {
|
|
99
|
+
background-color: white;
|
|
100
|
+
border-radius: 12px;
|
|
101
|
+
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);
|
|
102
|
+
width: 100%;
|
|
103
|
+
max-width: 400px;
|
|
104
|
+
box-sizing: border-box;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.toggle-button {
|
|
108
|
+
margin-top: -0.75rem;
|
|
109
|
+
margin-bottom: 1rem;
|
|
110
|
+
background: none;
|
|
111
|
+
border: none;
|
|
112
|
+
color: var(--qbo-primary-bg, #007bff);
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
font-size: 0.85rem;
|
|
115
|
+
padding: 0;
|
|
116
|
+
text-align: left;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/*.navbar {
|
|
120
|
+
display: flex;
|
|
121
|
+
justify-content: space-between;
|
|
122
|
+
align-items: center;
|
|
123
|
+
padding: 0 20px;
|
|
124
|
+
color: var( --qbo-nav-color, #333);
|
|
125
|
+
}*/
|
|
126
|
+
|
|
127
|
+
.logo {
|
|
128
|
+
display: flex;
|
|
129
|
+
align-items: center;
|
|
130
|
+
font-size: 20px;
|
|
131
|
+
font-weight: bold;
|
|
132
|
+
text-decoration: none;
|
|
133
|
+
color: #333;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.logo img {
|
|
137
|
+
height: 40px;
|
|
138
|
+
margin-right: 10px;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.alert {
|
|
142
|
+
background-color: #ffefef;
|
|
143
|
+
border: 1px solid #e57373;
|
|
144
|
+
color: #b71c1c;
|
|
145
|
+
padding: 0.75rem;
|
|
146
|
+
border-radius: var(--qbo-border-radius, 6px);
|
|
147
|
+
margin-bottom: var(--qbo-margin-vertical, 1rem);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
.success-message {
|
|
151
|
+
padding: 1rem;
|
|
152
|
+
border-radius: var(--qbo-border-radius, 8px);
|
|
153
|
+
border: 1px solid var(--qbo-success-border, #4caf50);
|
|
154
|
+
background-color: var(--qbo-success-bg, #e8f5e9);
|
|
155
|
+
color: var(--qbo-success-color, #2e7d32);
|
|
156
|
+
|
|
157
|
+
button {
|
|
158
|
+
background-color: var(--qbo-success-bg, #4caf50);
|
|
159
|
+
margin-top: 1rem;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
button:hover {
|
|
163
|
+
background-color: var(--qbo-success-hover-bg, #388e3c);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/*.password-field {
|
|
168
|
+
position: relative;
|
|
169
|
+
|
|
170
|
+
input {
|
|
171
|
+
padding-right: 60px;
|
|
172
|
+
}
|
|
173
|
+
}*/
|
package/src/Program.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
export * from './qbo-login.js';
|
|
3
|
+
export * from './qbo-register.js';
|
|
4
|
+
export * from './qbo-password.js';
|
|
5
|
+
export * from './qbo-2fa.js';
|
|
6
|
+
export * from './qbo-invite.js';
|
|
7
|
+
export * from './qbo-utils.js';
|
|
8
|
+
export * from './qbo-navbar.js';
|
|
9
|
+
export * from './qbo-form-header.js';
|
package/src/Program.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
export * from './qbo-login.js';
|
|
3
|
+
export * from './qbo-register.js';
|
|
4
|
+
export * from './qbo-password.js';
|
|
5
|
+
export * from './qbo-2fa.js';
|
|
6
|
+
export * from './qbo-invite.js';
|
|
7
|
+
export * from './qbo-utils.js';
|
|
8
|
+
export * from './qbo-navbar.js';
|
|
9
|
+
export * from './qbo-form-header.js';
|
|
10
|
+
//# sourceMappingURL=Program.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Program.js","sourceRoot":"","sources":["Program.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAE1B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAEhC,cAAc,sBAAsB,CAAC"}
|
package/src/Program.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
|
|
3
|
+
export * from './qbo-login.js';
|
|
4
|
+
export * from './qbo-register.js';
|
|
5
|
+
export * from './qbo-password.js';
|
|
6
|
+
export * from './qbo-2fa.js';
|
|
7
|
+
export * from './qbo-invite.js';
|
|
8
|
+
export * from './qbo-utils.js';
|
|
9
|
+
export * from './qbo-navbar.js';
|
|
10
|
+
|
|
11
|
+
export * from './qbo-form-header.js';
|
package/src/qbo-2fa.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
export declare class QboTwoFactor extends LitElement {
|
|
3
|
+
static styles: import("lit").CSSResult;
|
|
4
|
+
isPhoneChange: boolean;
|
|
5
|
+
isPhoneAdd: boolean;
|
|
6
|
+
isEmailConfirmation: boolean;
|
|
7
|
+
private email;
|
|
8
|
+
private phoneNumber;
|
|
9
|
+
private authenticator;
|
|
10
|
+
private authenticatorContent;
|
|
11
|
+
private code;
|
|
12
|
+
private provider;
|
|
13
|
+
private status;
|
|
14
|
+
private statusType;
|
|
15
|
+
private isResetAuthenticator;
|
|
16
|
+
private isCodeSent;
|
|
17
|
+
private isAuthenticatorSetup;
|
|
18
|
+
private skippedAuthenticatorEnrollment;
|
|
19
|
+
private isSignedIn2FA;
|
|
20
|
+
private handleSendCode;
|
|
21
|
+
private handleSignIn2FA;
|
|
22
|
+
private handlePhoneAdd;
|
|
23
|
+
private handlePhoneAddVerify;
|
|
24
|
+
private handleChangePhone;
|
|
25
|
+
private handleVerifyEmail;
|
|
26
|
+
private handleResendConfirmationEmail;
|
|
27
|
+
private handleVerifyPhone;
|
|
28
|
+
private handleAuthenticatorEnrollment;
|
|
29
|
+
private handleAuthenticatorEnrollmentVerify;
|
|
30
|
+
private handleResendCode;
|
|
31
|
+
private switchToPhoneChange;
|
|
32
|
+
private startAuthenticatorEnrollment;
|
|
33
|
+
private renderEnrollAuthenticator;
|
|
34
|
+
private renderEmailVerify;
|
|
35
|
+
private renderPhoneAdd;
|
|
36
|
+
private renderPhoneChange;
|
|
37
|
+
private renderPostSignInOptions;
|
|
38
|
+
private render2FASignIn;
|
|
39
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
40
|
+
}
|