-
Notifications
You must be signed in to change notification settings - Fork 3
Recognize setup #691
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Recognize setup #691
Changes from 11 commits
39ee8bf
b60f46c
e9817c8
0d673aa
b66ab2b
7bd16ba
43da855
01690ab
79e5c7e
af2a930
1ce8a57
6f3cc8d
ca4d39b
821537f
f56144a
f1b5aa8
0d316df
3929c3d
84922f6
f510de4
9c87943
3f074dc
4e3ea50
d6ca76a
ea83f91
3954b2e
792caa3
80263df
940b95c
4a89559
437bdb5
661bc5a
fb4ae5f
8d85363
d121969
136f3d3
fc57210
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| import baseConfig from '../../eslint.config.mjs'; | ||
|
|
||
| export default [ | ||
| { | ||
| ignores: [ | ||
| 'node_modules', | ||
| '*.md', | ||
| 'LICENSE', | ||
| '.swcrc', | ||
| '.babelrc', | ||
| '.env*', | ||
| '.bin', | ||
| 'dist', | ||
| '.eslintignore', | ||
| '*.html', | ||
| '*.svg', | ||
| '*.css', | ||
| 'public', | ||
| '*.json', | ||
| '*.d.ts', | ||
| ], | ||
| }, | ||
| ...baseConfig, | ||
| ]; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| { | ||
| "name": "@forgerock/recognize-app", | ||
| "version": "0.0.1", | ||
| "private": true, | ||
| "scripts": { | ||
| "build": "pnpm nx nxBuild", | ||
| "lint": "pnpm nx nxLint", | ||
| "preview": "pnpm nx nxPreview", | ||
| "serve": "pnpm nx nxServe" | ||
| }, | ||
| "dependencies": { | ||
| "@forgerock/journey-client": "workspace:*", | ||
| "@forgerock/recognize": "workspace:*" | ||
| }, | ||
| "nx": { | ||
| "tags": ["scope:e2e"] | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| <!doctype html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8" /> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
| <title>Recognize E2E Test Index | Ping Identity JavaScript SDK</title> | ||
| </head> | ||
| <body> | ||
| <div id="app"> | ||
| <h2>Recognize E2E Test Index | Ping Identity JavaScript SDK</h2> | ||
| </div> | ||
| <script type="module" src="index.ts"></script> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,37 @@ | ||||||||||||||||||||||||||||
| import { recognize } from '@forgerock/recognize'; | ||||||||||||||||||||||||||||
| import './styles.css'; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const client = recognize({ | ||||||||||||||||||||||||||||
| authorizationToken: 'USER_AUTHORIZATION_FROM_CUSTOMER', | ||||||||||||||||||||||||||||
| customer: 'CUSTOMER_NAME', | ||||||||||||||||||||||||||||
| key: 'IMAGE_ENCRYPTION_PUBLIC_KEY', | ||||||||||||||||||||||||||||
| keyID: 'IMAGE_ENCRYPTION_KEY_ID', | ||||||||||||||||||||||||||||
| transactionData: 'DATA_FROM_CUSTOMER_SERVER_TO_BE_SIGNED', | ||||||||||||||||||||||||||||
| wsURL: 'KEYLESS_AUTHENTICATION_SERVICE_URL', | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| client.subscribe({ | ||||||||||||||||||||||||||||
| next: (event) => { | ||||||||||||||||||||||||||||
| console.log('[recognize]', event.type, event.detail); | ||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||
| error: (err) => { | ||||||||||||||||||||||||||||
| console.error('[recognize] error', { | ||||||||||||||||||||||||||||
| code: err.code, | ||||||||||||||||||||||||||||
| message: err.message, | ||||||||||||||||||||||||||||
| name: err.name, | ||||||||||||||||||||||||||||
| cause: err.cause, | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||
| complete: (detail) => { | ||||||||||||||||||||||||||||
| console.log('[recognize] complete', detail); | ||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| const appEl = document.getElementById('app'); | ||||||||||||||||||||||||||||
| if (appEl) { | ||||||||||||||||||||||||||||
| client | ||||||||||||||||||||||||||||
| .init({ mode: 'mount', container: appEl, type: 'auth', username: 'USERNAME' }) | ||||||||||||||||||||||||||||
| .then((err) => { | ||||||||||||||||||||||||||||
| if (err) console.error('[recognize] init error', err); | ||||||||||||||||||||||||||||
| }); | ||||||||||||||||||||||||||||
|
Comment on lines
+29
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle the rejected Only the fulfilled path is handled. If Proposed fix if (appEl) {
client
.init({ mode: 'mount', container: appEl, type: 'auth', username: 'USERNAME' })
.then((err) => {
if (err) console.error('[recognize] init error', err);
- });
+ })
+ .catch((err) => {
+ console.error('[recognize] init rejected', err);
+ });
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| body { | ||
| font-family: | ||
| -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif; | ||
| margin: 0; | ||
| padding: 2rem; | ||
| } | ||
|
|
||
| #app { | ||
| max-width: 960px; | ||
| margin: 0 auto; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| { | ||
| "extends": "../../tsconfig.base.json", | ||
| "compilerOptions": { | ||
| "outDir": "dist", | ||
| "types": ["node"], | ||
| "rootDir": "src", | ||
| "module": "esnext", | ||
| "moduleResolution": "bundler", | ||
| "tsBuildInfoFile": "dist/tsconfig.app.tsbuildinfo" | ||
| }, | ||
| "exclude": [ | ||
| "out-tsc", | ||
| "dist", | ||
| "src/**/*.spec.ts", | ||
| "src/**/*.test.ts", | ||
| "eslint.config.js", | ||
| "eslint.config.cjs", | ||
| "eslint.config.mjs" | ||
| ], | ||
| "include": ["src/**/*.ts"], | ||
| "references": [ | ||
| { | ||
| "path": "../../packages/recognize/tsconfig.lib.json" | ||
| }, | ||
| { | ||
| "path": "../../packages/journey-client/tsconfig.lib.json" | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "extends": "../../tsconfig.base.json", | ||
| "files": [], | ||
| "include": [], | ||
| "references": [ | ||
| { | ||
| "path": "./tsconfig.app.json" | ||
| } | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| import { defineConfig } from 'vite'; | ||
| import { dirname, resolve } from 'path'; | ||
| import { fileURLToPath } from 'url'; | ||
|
|
||
| const __dirname = dirname(fileURLToPath(import.meta.url)); | ||
|
|
||
| export default defineConfig(() => ({ | ||
| root: __dirname + '/src', | ||
| cacheDir: '../../node_modules/.vite/e2e/recognize-app', | ||
| publicDir: __dirname + '/public', | ||
| server: { | ||
| port: 8443, | ||
| host: 'localhost', | ||
| }, | ||
| preview: { | ||
| port: 8443, | ||
| host: 'localhost', | ||
| }, | ||
| plugins: [], | ||
| build: { | ||
| outDir: __dirname + '/dist', | ||
| emptyOutDir: true, | ||
| reportCompressedSize: true, | ||
| rollupOptions: { | ||
| input: { | ||
| main: resolve(__dirname + '/src', 'index.html'), | ||
| }, | ||
| output: { | ||
| entryFileNames: '[name]/main.js', | ||
| }, | ||
| }, | ||
| }, | ||
| })); |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should probably update this.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Before we officially publish this, we will need to add a summary, instructions, example code, and how to find more documentation and such to this README. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| # recognize | ||
|
|
||
| This library was generated with [Nx](https://nx.dev). | ||
|
|
||
| ## Building | ||
|
|
||
| Run `nx build recognize` to build the library. | ||
|
|
||
| ## Running unit tests | ||
|
|
||
| Run `nx test recognize` to execute the unit tests via [Vitest](https://vitest.dev/). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| import baseConfig from '../../eslint.config.mjs'; | ||
|
|
||
| export default [ | ||
| ...baseConfig, | ||
| { | ||
| files: ['**/*.json'], | ||
| rules: { | ||
| '@nx/dependency-checks': [ | ||
| 'error', | ||
| { | ||
| ignoredFiles: [ | ||
| '{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}', | ||
| '{projectRoot}/vite.config.{js,ts,mjs,mts}', | ||
| '{projectRoot}/src/lib/recognize-sdk/**/*', | ||
| ], | ||
| }, | ||
| ], | ||
| }, | ||
| languageOptions: { | ||
| parser: await import('jsonc-eslint-parser'), | ||
| }, | ||
| }, | ||
| { | ||
| ignores: ['**/out-tsc'], | ||
| }, | ||
| ]; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| { | ||
| "name": "@forgerock/recognize", | ||
| "version": "0.0.1", | ||
| "private": true, | ||
| "type": "module", | ||
| "exports": { | ||
| ".": { | ||
| "types": "./dist/src/index.d.ts", | ||
| "import": "./dist/src/index.js", | ||
| "default": "./dist/src/index.js" | ||
| }, | ||
| "./package.json": "./package.json" | ||
| }, | ||
| "main": "./dist/src/index.js", | ||
| "module": "./dist/src/index.js", | ||
| "types": "./dist/src/index.d.ts", | ||
| "dependencies": { | ||
| "tslib": "^2.3.0" | ||
| }, | ||
| "devDependencies": { | ||
| "@aracna/web-components": "^1.1.18" | ||
| }, | ||
| "nx": { | ||
| "tags": ["scope:package"], | ||
| "targets": { | ||
| "build": { | ||
| "executor": "@nx/js:tsc", | ||
| "outputs": ["{options.outputPath}"], | ||
| "options": { | ||
| "outputPath": "packages/recognize/dist", | ||
| "main": "packages/recognize/src/index.ts", | ||
| "tsConfig": "packages/recognize/tsconfig.lib.json", | ||
| "generatePackageJson": false, | ||
| "assets": [ | ||
| { | ||
| "input": "packages/recognize/src/lib/recognize-sdk", | ||
| "glob": "**/*", | ||
| "output": "./src/lib/recognize-sdk" | ||
| } | ||
| ] | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We like to use the convention of separating runtime code and type definitions. We try to only export the runtime code in the root
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| export { recognize, RecognizeError } from './lib/recognize.js'; | ||
| export { RecognizeErrorCode } from './lib/defs/recognize-error-code.js'; | ||
| export type { | ||
| RecognizeSessionType, | ||
| RecognizeWebComponent, | ||
| RecognizeWebComponentClient, | ||
| RecognizeWebComponentCompleteData, | ||
| RecognizeWebComponentConfiguration, | ||
| RecognizeWebComponentEvent, | ||
| RecognizeWebComponentFrameResultsEventDetail, | ||
| RecognizeWebComponentInitOptions, | ||
| RecognizeWebComponentObserver, | ||
| RecognizeWebComponentStepChangeEventDetail, | ||
| RecognizeWebComponentUnsubscribe, | ||
| RecognizeWebComponentVideoFrameQualityEventDetail, | ||
| RecognizeWebComponentWebSocketCloseEventDetail, | ||
| RecognizeWebComponentWebSocketOpenEventDetail, | ||
| } from './lib/recognize.types.js'; |
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We like to treat errors within the SDK as plain objects, rather than extensions of the
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| import { RecognizeErrorCode } from '../defs/recognize-error-code.js'; | ||
|
|
||
| /** @public */ | ||
| export class RecognizeError extends Error { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we enforce functional patterns here?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
| code: RecognizeErrorCode; | ||
|
|
||
| constructor(code: RecognizeErrorCode, options?: ErrorOptions) { | ||
| super(RecognizeErrorCode[code], options); | ||
|
|
||
| this.code = code; | ||
| this.name = 'RecognizeError'; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| /** @internal */ | ||
| export const CAMERA_ONLY_DISABLE_STEPS: string[] = [ | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure the benefit - if it's helpful or not, but we can make this an If it's possible for any string then this can be ignored, but it seems the steps here are finite.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok (I'll retrieve it from KeylessStep) |
||
| 'bootstrap', | ||
| 'camera-instructions', | ||
| 'done', | ||
| 'error', | ||
| 'microphone-permission', | ||
| 'server-computation', | ||
| 'stm-choice', | ||
| 'stm-qrcode', | ||
| ]; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| /* | ||
| * | ||
| * Copyright © 2026 Ping Identity Corporation. All right reserved. | ||
| * | ||
| * This software may be modified and distributed under the terms | ||
| * of the MIT license. See the LICENSE file for details. | ||
| * | ||
| */ | ||
|
|
||
| /** @public */ | ||
| export enum RecognizeErrorCode { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typically we try to avoid The alternative approach would be to use a typed i.e. // produces a runtime object and a strictly typed object
const RecognizeErrorCode = {
SDK_ERROR: 1000
} as const
// if you want a union of allowed keys
export type RecognizeErrorCodes = keyof typeof RecognizeErrorCode
// if you want a union of allowed values
export type RecognizeErrorCodes = typeof RecognizeErrorCodes[keyof typeof RecognizeErrorCodes]
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We try to avoid enums in our code. I'm guessing this enum is preferred to avoid writing a structure for runtime and a duplicate structure for types, which both need to be identical. What we do is use a combination of
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we enforce functional patterns here?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
| SDK_ERROR = 1000, | ||
| SDK_NOT_CONFIGURED = 1001, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We are defining error codes here, but a lot of them seem to be unused. Are they being handled by wasm pre-compiled code?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this enum is the shared errors, it's not meant to be used within the proxy module. the end consumer of this will be actual integrator. the code is mapped from the native websdk error code to this one for usage in the callbacks. |
||
| SDK_INVALID_CONFIGURATION = 1002, | ||
| SDK_LOGGING_CONFIGURATION_FAILED = 1003, | ||
| SDK_STORAGE_FAILED = 1004, | ||
| SDK_USER_CANCELLED = 1005, | ||
| SDK_TIMEOUT = 1006, | ||
| SDK_NO_NETWORK_CONNECTION = 1007, | ||
| SDK_DYNAMIC_LINKING_PAYLOAD_MALFORMED = 1008, | ||
| SDK_ARTIFACT_RETRIEVE_FAILED = 1009, | ||
| SDK_INVALID_CLIENT_STATE = 1010, | ||
| SDK_WEB_SOCKET_ERROR = 1011, | ||
| SDK_OUTDATED_APP = 1012, | ||
| SDK_WEB_ASSEMBLY_IMPORT_FAILED = 1013, | ||
| SDK_WEB_ASSEMBLY_IMPORT_NOT_FULFILLED = 1014, | ||
| SDK_WEB_ASSEMBLY_ERROR = 1015, | ||
| SDK_INVALID_CUSTOMER_PROPERTIES = 1016, | ||
| CAMERA_ERROR = 2000, | ||
| CAMERA_NOT_FOUND = 2001, | ||
| CAMERA_PERMISSION_DENIED = 2002, | ||
| CAMERA_NOT_SUPPORTED = 2003, | ||
| CORE_ERROR = 3000, | ||
| CORE_NOT_ENOUGH_API_KEY_SEATS = 3001, | ||
| CORE_USER_ALREADY_ENROLLED = 3002, | ||
| CORE_USER_NOT_ENROLLED = 3003, | ||
| CORE_FACE_NOT_MATCHING = 3004, | ||
| CORE_NOT_ENOUGH_CIRCUITS = 3005, | ||
| CORE_SECRET_NOT_FOUND = 3006, | ||
| CORE_USER_LOCKED_OUT = 3007, | ||
| CORE_CUSTOMER_NOT_FOUND = 3008, | ||
| BIOM_ERROR = 4000, | ||
| BIOM_REJECTED = 4001, | ||
| BIOM_GENUINE_PRESENCE_NOT_ESTABLISHED = 4002, | ||
| BIOM_LIVENESS_ENVIRONMENT_AWARE_NOT_SUPPORTED = 4003, | ||
| BIOM_DEVICE_ENVIRONMENT_AWARE_NOT_SUPPORTED = 4004, | ||
| SERVER_ERROR = 5000, | ||
| SERVER_ENCRYPTION_FAILED = 5001, | ||
| SERVER_RECOGNITION_FAILED = 5002, | ||
| SERVER_AUTHORIZATION_FAILED = 5003, | ||
| SERVER_TIMEOUT = 5004, | ||
| SECURITY_ERROR = 6000, | ||
| SECURITY_DEVICE_NOT_GENUINE = 6001, | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.