diff --git a/packages/connect-react/src/components/CorbadoConnectDemo.tsx b/packages/connect-react/src/components/CorbadoConnectDemo.tsx index ca5631b69..9b2a54ce7 100644 --- a/packages/connect-react/src/components/CorbadoConnectDemo.tsx +++ b/packages/connect-react/src/components/CorbadoConnectDemo.tsx @@ -31,6 +31,7 @@ const getListOfPasskeys = () => { authenticatorAAGUID: 'authenticatorAAGUID', sourceOS: 'Windows 10', sourceBrowser: 'Chrome', + createdInCurrentBrowser: true, lastUsed: '2024-10-03 14:45:57', created: '2024-10-03 14:45:57', status: '' as any, @@ -59,6 +60,7 @@ const getListOfPasskeys = () => { lastUsed: '2024-10-03 14:45:57', sourceBrowser: 'Chrome', sourceOS: 'macOS', + createdInCurrentBrowser: false, status: 'active', transport: ['nfc', 'usb'], createdMs: 1735689600000, diff --git a/packages/connect-react/src/components/passkeyList/DeleteModal.tsx b/packages/connect-react/src/components/passkeyList/DeleteModal.tsx index d46b3b181..f7383325b 100644 --- a/packages/connect-react/src/components/passkeyList/DeleteModal.tsx +++ b/packages/connect-react/src/components/passkeyList/DeleteModal.tsx @@ -26,7 +26,7 @@ const DeleteModal = ({ onDeleteClick, hide, passkey }: Props) => ( lastUsed={passkey.lastUsed} browser={passkey.sourceBrowser} os={passkey.sourceOS} - isThisDevice={false} + createdInCurrentBrowser={passkey.createdInCurrentBrowser} isSynced={passkey.backupState} isHybrid={passkey.transport.includes('hybrid')} key={passkey.id} diff --git a/packages/connect-react/src/components/passkeyList/PasskeyList.tsx b/packages/connect-react/src/components/passkeyList/PasskeyList.tsx index 240ecb6df..69a0ce045 100644 --- a/packages/connect-react/src/components/passkeyList/PasskeyList.tsx +++ b/packages/connect-react/src/components/passkeyList/PasskeyList.tsx @@ -63,7 +63,7 @@ const PasskeyList: FC = ({ lastUsed={passkey.lastUsed} browser={passkey.sourceBrowser} os={passkey.sourceOS} - isThisDevice={false} + createdInCurrentBrowser={passkey.createdInCurrentBrowser} isSynced={passkey.backupState} isHybrid={passkey.transport.includes('hybrid')} key={passkey.id} diff --git a/packages/connect-react/src/components/shared/PasskeyListItem.tsx b/packages/connect-react/src/components/shared/PasskeyListItem.tsx index 0562e6646..0a27d0749 100644 --- a/packages/connect-react/src/components/shared/PasskeyListItem.tsx +++ b/packages/connect-react/src/components/shared/PasskeyListItem.tsx @@ -17,7 +17,7 @@ export type Props = { lastUsed: string | Date; browser: string; os: 'Windows' | 'macOS' | 'Android' | 'iOS' | string; - isThisDevice?: boolean; + createdInCurrentBrowser?: boolean; isSynced?: boolean; isHybrid?: boolean; onDeleteClick?: () => void; @@ -33,7 +33,7 @@ export const PasskeyListItem: FC = ({ onDeleteClick, isSynced, isHybrid, - isThisDevice, + createdInCurrentBrowser, }) => { const getTags = () => { const tags = []; @@ -46,8 +46,13 @@ export const PasskeyListItem: FC = ({ tags.push({ text: 'Hybrid', icon: (className: string) => ShieldTickIcon({ className }) }); } - if (isThisDevice) { - tags.push({ text: 'Seen on this device', icon: (className: string) => EyeIcon({ className }) }); + if (createdInCurrentBrowser) { + tags.push({ + text: 'Created in this browser', + title: + 'This passkey was registered from this browser. It may be stored in a password manager or on another device; this does not confirm it is still available.', + icon: (className: string) => EyeIcon({ className }), + }); } return tags; @@ -71,10 +76,10 @@ export const PasskeyListItem: FC = ({
{name}
- {getTags().map(({ text, icon }) => ( + {getTags().map(({ text, title, icon }) => ( {icon('cb-passkey-list-item-tag-icon')} - {text} + {text} ))}
diff --git a/packages/web-core/openapi/spec_v2.yaml b/packages/web-core/openapi/spec_v2.yaml index b82b2cca1..de93c2e2e 100644 --- a/packages/web-core/openapi/spec_v2.yaml +++ b/packages/web-core/openapi/spec_v2.yaml @@ -1859,6 +1859,12 @@ components: type: string sourceBrowser: type: string + createdInCurrentBrowser: + type: boolean + description: >- + Whether this passkey's recorded creation environment matches the current browser handle. + Omitted when no browser context is supplied. False means no matching creation record, + not that the passkey is unavailable. This does not verify current authenticator availability. lastUsed: type: string description: Timestamp of when the passkey was last used in yyyy-MM-dd'T'HH:mm:ss format diff --git a/packages/web-core/src/api/v2/api.ts b/packages/web-core/src/api/v2/api.ts index 064632211..1096fd576 100644 --- a/packages/web-core/src/api/v2/api.ts +++ b/packages/web-core/src/api/v2/api.ts @@ -2491,6 +2491,12 @@ export interface Passkey { * @memberof Passkey */ 'sourceBrowser': string; + /** + * Whether this passkey\'s recorded creation environment matches the current browser handle. Omitted when no browser context is supplied. False means no matching creation record, not that the passkey is unavailable. This does not verify current authenticator availability. + * @type {boolean} + * @memberof Passkey + */ + 'createdInCurrentBrowser'?: boolean; /** * Timestamp of when the passkey was last used in yyyy-MM-dd\'T\'HH:mm:ss format * @type {string}