Skip to content

Commit

Permalink
fix: added nonce to sdks and update readme (#1041)
Browse files Browse the repository at this point in the history
## Related Issues

Related descope/etc#2098
  • Loading branch information
nirgur authored Mar 6, 2025
1 parent 2fac25d commit 597bd34
Show file tree
Hide file tree
Showing 16 changed files with 57 additions and 17 deletions.
3 changes: 3 additions & 0 deletions packages/sdks/angular-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,9 @@ export class AppComponent {
Use a custom style name or keep empty to use the default style.
styleId="my-awesome-style"
Set a CSP nonce that will be used for style and script tags.
nonce="rAnd0m"
logger is an object describing how to log info, warn and errors.
NOTE: logger is not required. If not provided, the logs will be printed to the console.
Example:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export class DescopeComponent implements OnInit, OnChanges {
ref: HTMLElement
) => boolean | Promise<boolean>;
@Input() client: Record<string, any>;
@Input() nonce: string;
@Input() form: Record<string, any>;
@Input() logger: ILogger;
@Input() styleId: string;
Expand Down Expand Up @@ -172,6 +173,10 @@ export class DescopeComponent implements OnInit, OnChanges {
this.webComponent.setAttribute('client', JSON.stringify(this.client));
}

if (this.nonce) {
this.webComponent.setAttribute('nonce', JSON.stringify(this.nonce));
}

if (this.form) {
this.webComponent.setAttribute('form', JSON.stringify(this.form));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
[errorTransformer]="errorTransformer"
[onScreenUpdate]="onScreenUpdate"
[client]="client"
[nonce]="nonce"
[form]="form"
[logger]="logger"
[styleId]="styleId"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class SignInFlowComponent {
ref: HTMLElement
) => boolean | Promise<boolean>;
@Input() client: Record<string, any>;
@Input() nonce: string;
@Input() form: Record<string, any>;
@Input() logger: ILogger;
@Input() styleId: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
[errorTransformer]="errorTransformer"
[onScreenUpdate]="onScreenUpdate"
[client]="client"
[nonce]="nonce"
[form]="form"
[logger]="logger"
[styleId]="styleId"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class SignUpFlowComponent {
ref: HTMLElement
) => boolean | Promise<boolean>;
@Input() client: Record<string, any>;
@Input() nonce: string;
@Input() form: Record<string, any>;
@Input() logger: ILogger;
@Input() styleId: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
[errorTransformer]="errorTransformer"
[onScreenUpdate]="onScreenUpdate"
[client]="client"
[nonce]="nonce"
[form]="form"
[logger]="logger"
[styleId]="styleId"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export class SignUpOrInFlowComponent {
ref: HTMLElement
) => boolean | Promise<boolean>;
@Input() client: Record<string, any>;
@Input() nonce: string;
@Input() form: Record<string, any>;
@Input() logger: ILogger;
@Input() styleId: string;
Expand Down
2 changes: 2 additions & 0 deletions packages/sdks/react-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ const App = () => {

// Use a custom style name or keep empty to use the default style.
// styleId="my-awesome-style"
// Set a CSP nonce that will be used for style and script tags
//nonce="rAnd0m"

/>
)
Expand Down
2 changes: 2 additions & 0 deletions packages/sdks/react-sdk/src/components/Descope.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const Descope = React.forwardRef<HTMLElement, DescopeProps>(
logger,
tenant,
theme,
nonce,
locale,
debug,
client,
Expand Down Expand Up @@ -176,6 +177,7 @@ const Descope = React.forwardRef<HTMLElement, DescopeProps>(
{...{
// attributes
'theme.attr': theme,
'nonce.attr': nonce,
'locale.attr': locale,
'form.attr': form,
'client.attr': client,
Expand Down
1 change: 1 addition & 0 deletions packages/sdks/react-sdk/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export type DescopeProps = {
theme?: ThemeOptions;
// If locale is not provided - the browser's locale will be used
locale?: string;
nonce?: string;
autoFocus?: AutoFocusOptions;
validateOnBlur?: boolean;
restartOnError?: boolean;
Expand Down
1 change: 1 addition & 0 deletions packages/sdks/vue-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ app.mount('#app');
<!-- form="{ email: '[email protected]' }" form is an object the initial form context that is used in screens inputs in the flow execution. Used to inject predifined input values on flow start such as custom inputs, custom attrbiutes and other inputs. Keys passed can be accessed in flows actions, conditions and screens prefixed with "form.". NOTE: form is not required. If not provided, 'form' context key will be empty before user input. -->
<!-- client="{ version: '1.2.3' }" client is an object the initial client context in the flow execution. Keys passed can be accessed in flows actions and conditions prefixed with "client.". NOTE: client is not required. If not provided, context key will be empty. -->
<!-- styleId="my-awesome-style" Use a custom style name or keep empty to use the default style. -->
<!-- nonce="rAnd0m" Set a CSP nonce that will be used for style and script tags -->
</template>
<script setup>
Expand Down
4 changes: 4 additions & 0 deletions packages/sdks/vue-sdk/src/Descope.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
:onScreenUpdate.prop="onScreenUpdate"
:form.attr="formStr"
:client.attr="clientStr"
:nonce.attr="nonce"
@success="onSuccess"
@error="onError"
@ready="onReady"
Expand Down Expand Up @@ -110,6 +111,9 @@ const props = defineProps({
styleId: {
type: String,
},
nonce: {
type: String,
},
});
// const emit = defineEmits(['success', 'error', 'ready']);
const emit = defineEmits<{
Expand Down
30 changes: 14 additions & 16 deletions packages/sdks/web-component/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,20 @@ NOTE: This package is a part of a monorepo. so if you make changes in a dependen

## Optional Attributes

| Attribute | Available options | Default value |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| base-url | Custom Descope base URL | **""** |
| theme | **"light"** - Light theme</br>**"dark"** - Dark theme</br>**"os"** - Auto select a theme based on the OS theme settings | **"light"** |
| debug | **"true"** - Enable debugger</br>**"false"** - Disable debugger | **"false"** |
| preview | **"true"** - Run flow in a preview mode</br>**"false"** - Do run flow in a preview mode | **"false"** |
| auto-focus | **"true"** - Automatically focus on the first input of each screen</br>**"false"** - Do not automatically focus on screen's inputs</br>**"skipFirstScreen"** - Automatically focus on the first input of each screen, except first screen | **"true"** |

| validate-on-blur | **"true"** - Triggers the input validation upon blur in addition to the validation on submit</br>**"false"** - Do not triggers validation upon blur</br> | **"false"** |

| restart-on-error | **"true"** - In case of flow version mismatch, will restart the flow if the components version was not changed</br>**"false"** - Do not restart the flow automatically</br> | **"false"** |

| storage-prefix | **String** - A prefix to add to the key of the local storage when persisting tokens | **""** |
| store-last-authenticated-user | **"true"** - Stores last-authenticated user details in local storage when flow is completed</br>**"false"** - Do not store last-auth user details. Disabling this flag may cause last-authenticated user features to not function properly | **"true"** |
| keep-last-authenticated-user-after-logout | **"true"** - Do not clear the last authenticated user details from the browser storage after logout</br>**"false"** - Clear the last authenticated user details from the browser storage after logout | **"false"** |
| style-id | **"String"** - Set a specific style to load rather then the default style | **""** |
| Attribute | Available options | Default value |
| ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- |
| base-url | Custom Descope base URL | **""** |
| theme | **"light"** - Light theme</br>**"dark"** - Dark theme</br>**"os"** - Auto select a theme based on the OS theme settings | **"light"** |
| debug | **"true"** - Enable debugger</br>**"false"** - Disable debugger | **"false"** |
| preview | **"true"** - Run flow in a preview mode</br>**"false"** - Do run flow in a preview mode | **"false"** |
| auto-focus | **"true"** - Automatically focus on the first input of each screen</br>**"false"** - Do not automatically focus on screen's inputs</br>**"skipFirstScreen"** - Automatically focus on the first input of each screen, except first screen | **"true"** |
| validate-on-blur | **"true"** - Triggers the input validation upon blur in addition to the validation on submit</br>**"false"** - Do not triggers validation upon blur</br> | **"false"** |
| restart-on-error | **"true"** - In case of flow version mismatch, will restart the flow if the components version was not changed</br>**"false"** - Do not restart the flow automatically</br> | **"false"** |
| storage-prefix | **String** - A prefix to add to the key of the local storage when persisting tokens | **""** |
| store-last-authenticated-user | **"true"** - Stores last-authenticated user details in local storage when flow is completed</br>**"false"** - Do not store last-auth user details. Disabling this flag may cause last-authenticated user features to not function properly | **"true"** |
| keep-last-authenticated-user-after-logout | **"true"** - Do not clear the last authenticated user details from the browser storage after logout</br>**"false"** - Clear the last authenticated user details from the browser storage after logout | **"false"** |
| style-id | **"String"** - Set a specific style to load rather then the default style | **""** |
| nonce | **"String"** - Set a CSP nonce that will be used for style and script tags | **""** |

## Optional Properties

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,6 @@ class BaseDescopeWc extends BaseClass {
}

async init() {
this.#handleNonce();
this.flowStatus = 'loading';
['ready', 'error', 'success'].forEach((status: FlowStatus) =>
this.addEventListener(status, () => {
Expand All @@ -539,6 +538,7 @@ class BaseDescopeWc extends BaseClass {
this.#debugState.update({ isDebug: this.debug });

this.#validateAttrs();
this.#handleNonce();

if (await this.#getIsFlowsVersionMismatch()) {
this.loggerWrapper.error(
Expand Down
18 changes: 18 additions & 0 deletions packages/sdks/web-component/test/descope-wc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5469,6 +5469,24 @@ describe('web-component', () => {
});
});

describe('CSP', () => {
it('should add nonce to window', async () => {
startMock.mockReturnValue(generateSdkResponse());

pageContent = `<div>Loaded123</div><descope-link class="descope-link" href="{{user.name}}">ho!</descope-link>`;

document.body.innerHTML = `<descope-wc flow-id="otpSignInEmail" project-id="1" nonce="123456"></descope-wc>`;

await waitFor(() => screen.getByShadowText('Loaded123'), {
timeout: WAIT_TIMEOUT,
});

await waitFor(() => expect(window.DESCOPE_NONCE).toBe('123456'), {
timeout: WAIT_TIMEOUT,
});
});
});

describe('custom screen', () => {
it('should call the onScreenUpdate with the correct params', async () => {
startMock.mockReturnValue(
Expand Down

0 comments on commit 597bd34

Please sign in to comment.