Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
name: CI

env:
NODE_VERSION: 18.0.0
NODE_VERSION: 22.14
RUNID_VERSION_SUFFIX: ${{ github.run_id }}.${{ github.run_attempt }}

on:
workflow_dispatch:
pull_request:
push:
branches: [ main ]
branches: [main]

jobs:
build:
Expand Down Expand Up @@ -60,16 +60,16 @@ jobs:
yarn pack --filename ../transmitsecurity-riskid-reactjs-ts-v$PACKAGE_VERSION.tgz
cd ..
- name: Archive NPM package
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
if-no-files-found: error
retention-days: 30
name: react-ts-riskid-npm-package
path: package/transmitsecurity-riskid-reactjs-ts-v*.tgz
- name: Archive failure data
if: ${{ failure() }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: failure-data
path: |
/home/runner/.npm/_logs
/home/runner/.npm/_logs
18 changes: 9 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: Release Artifact

env:
NODE_VERSION: 18.0.0
NODE_VERSION: 22.14
RUNID_VERSION_SUFFIX: ${{ github.run_id }}.${{ github.run_attempt }}

on:
Expand Down Expand Up @@ -50,7 +50,7 @@ jobs:

- name: Archive failure data
if: ${{ failure() }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: failure-data
path: |
Expand All @@ -67,15 +67,15 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://npm.pkg.github.com'
registry-url: "https://npm.pkg.github.com"
always-auth: true

- name: Fetch cached workspace
uses: actions/cache@v3
with:
path: ${{ github.workspace }}
key: ${{ runner.os }}-${{ env.RUNID_VERSION_SUFFIX }}

- name: Enable Corepack
run: corepack enable

Expand All @@ -90,7 +90,7 @@ jobs:

- name: Archive failure data
if: ${{ failure() }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: failure-data
path: |
Expand All @@ -107,15 +107,15 @@ jobs:
uses: actions/setup-node@v3
with:
node-version: ${{ env.NODE_VERSION }}
registry-url: 'https://registry.npmjs.org'
registry-url: "https://registry.npmjs.org"
always-auth: true

- name: Fetch cached workspace
uses: actions/cache@v3
with:
path: ${{ github.workspace }}
key: ${{ runner.os }}-${{ env.RUNID_VERSION_SUFFIX }}

- name: Enable Corepack
run: corepack enable

Expand All @@ -130,8 +130,8 @@ jobs:

- name: Archive failure data
if: ${{ failure() }}
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: failure-data
path: |
/home/runner/.npm/_logs
/home/runner/.npm/_logs
1 change: 1 addition & 0 deletions demo/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ function App() {
const accountProtectionOptions: DRSConfigOptions = {
userId: 'demo-user-id',
initSuccessLog: 'Detection and Response SDK successfully initialized',
enableSessionToken: true,
};

return (
Expand Down
6 changes: 5 additions & 1 deletion demo/src/InnerComponent.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useTSAccountProtection } from '@transmitsecurity/riskid-reactjs-ts';

function InnerComponent() {
const { triggerActionEvent, setAuthenticatedUser, clearUser } = useTSAccountProtection();
const { triggerActionEvent, setAuthenticatedUser, clearUser, getSessionToken } = useTSAccountProtection();

return (
<>
Expand All @@ -21,6 +21,10 @@ function InnerComponent() {
style={{width: '100px', height: '100px' }}
onClick={() => clearUser()}
>Reset</button>
<button
style={{width: '100px', height: '100px' }}
onClick={getSessionToken}
>Get Session Token</button>
</>
);
};
Expand Down
4 changes: 4 additions & 0 deletions package/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog


## Version 1.2.0
1. Expose `getSessionToken()` method from the SDK.

## Version 1.1.1
1. Update react quickstart documentation link in package README

Expand Down
10 changes: 8 additions & 2 deletions package/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,21 @@ import { TSAccountProtectionProvider } from '@transmitsecurity/riskid-reactjs-ts

## Step 4: Use the React library

The example below demonstrates triggering a login event from a login button, setting and clearing a user.
The example below demonstrates triggering a login event from a login button, setting and clearing a user and obtaining a session token.

- `triggerActionEvent()` receives an action type and returns a response that includes the `actionToken`. To obtain risk recommendations for sensitive actions, your application should report these actions. To do this, add the code below to relevant user interactions (such as the Login button `click` event handler). The library allows reporting on events with the following action types: `login`, `register`, `transaction`, `password_reset`, `logout`, `checkout`, `account_details_change`, `account_auth_change`, `withdraw` or `credits_change`.

- `setAuthenticatedUser()` sets the user context for all subsequent events in the browser session (or until the user is explicitly cleared). It should be set only after you've fully authenticated the user (including, for example, any 2FA that was required). Receives an opaque identifier of the user in your system ([USER_ID] in the snippet), which shouldn't contain any personal info.

- `clearUser()` clears the user context for all subsequent events in the browser session.

- `getSessionToken()` retrieves the current device session token as a string, that can be used to trigger action events via backend API.

```js
import { useTSAccountProtection } from '@transmitsecurity/riskid-reactjs-ts';

function InnerComponent() {
const { triggerActionEvent, setAuthenticatedUser, clearUser } = useTSAccountProtection();
const { triggerActionEvent, setAuthenticatedUser, clearUser, getSessionToken } = useTSAccountProtection();

return (
<>
Expand All @@ -69,6 +71,10 @@ function InnerComponent() {
style={{width: '100px', height: '100px' }}
onClick={() => clearUser()}
>Reset</button>
<button
style={{width: '100px', height: '100px' }}
onClick={getSessionToken}
>Get Session Token</button>
</>
);
};
Expand Down
26 changes: 24 additions & 2 deletions package/TSAccountProtectionProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const SDK_LOAD_ERR = 'SDK load error';
const SDK_TRIGGER_ACTION_ERR = 'Error sending action event';
const SDK_AUTHENTICATE_USER_ERR = 'Error authenticating user';
const SDK_CLEAR_USER_ERR = 'Error clearing user';
const SDK_GET_SESSION_TOKEN_ERR = 'Error getting session token';

type ProviderState = DRSConfigOptions & {
initialized: Promise<boolean>;
Expand Down Expand Up @@ -68,6 +69,12 @@ type ErrHandler = (err: any) => void;
* A string to log when the sdk initialization completes. If not provided - logging will be skipped.
*/
initSuccessLog?: string;

/**
* Setting that determines if session token is enabled
* Default: false
*/
enableSessionToken?: boolean;
}

interface QuerablePromise extends Promise<any> {
Expand Down Expand Up @@ -148,6 +155,7 @@ const buildProviderState = (clientId: string, options?: DRSConfigOptions): Provi
return {
initialized: new Promise((res) => undefined), // making default promise in pending state
clientId,
enableSessionToken: options?.enableSessionToken ?? false,
serverUrl: options?.serverUrl ?? (options?.serverPath || 'https://api.transmitsecurity.io/risk-collect/'),
sdkVersion,
sdkLoadUrl: options?.sdkLoadUrl ?? generateSdkUrl(sdkVersion),
Expand Down Expand Up @@ -213,8 +221,8 @@ export function TSAccountProtectionProvider({
const initializedPromise = makeQuerablePromise(providerState.initialized);
if (initializedPromise.status != PromiseStatus.Fulfilled && !window.myTSAccountProtection) {
try {
const serverPath = providerState.serverUrl;
window.myTSAccountProtection = new TSAccountProtection(providerState.clientId, { serverPath });
const { serverUrl: serverPath, enableSessionToken } = providerState;
window.myTSAccountProtection = new TSAccountProtection(providerState.clientId, { serverPath, enableSessionToken});
try {
await window.myTSAccountProtection.init(providerState?.userId);
if (providerState.initSuccessLog) {
Expand Down Expand Up @@ -286,6 +294,19 @@ function getClearUserFunc(providerState: ProviderState, providerDispatch: Functi
}
}

function getSessionTokenFunc(providerState: ProviderState) {
return async function getSessionToken(): Promise<string | null> {
if (await providerState.initialized) {
try {
return await window.myTSAccountProtection?.getSessionToken();
} catch (err) {
(providerState.onError as ErrHandler)(buildSdkError(err, SDK_GET_SESSION_TOKEN_ERR));
}
}
return null;
}
}

const useAccountProtectionContext = () => {
const context = useContext(AccountProtectionContext);
if (context === undefined) {
Expand All @@ -302,5 +323,6 @@ export const useTSAccountProtection = () => {
triggerActionEvent: getTriggerActionEventFunc(state),
setAuthenticatedUser: getAuthenticatedUserFunc(state, dispatch),
clearUser: getClearUserFunc(state, dispatch),
getSessionToken: getSessionTokenFunc(state),
};
};
4 changes: 2 additions & 2 deletions package/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@transmitsecurity/riskid-reactjs-ts",
"version": "1.1.1",
"version": "1.2.0",
"license": "SEE LICENSE IN LICENSE",
"module": "./dist/index.es.js",
"main": "./dist/index.cjs.js",
Expand Down Expand Up @@ -52,7 +52,7 @@
"react": "17.0.2",
"react-error-overlay": "6.0.9",
"typescript": "4.9.4",
"vite": "2.9.18",
"vite": "6.3.4",
"vite-plugin-dts": "1.7.1",
"vite-plugin-environment": "1.1.0",
"vite-plugin-rewrite-all": "0.1.2",
Expand Down
Loading