Skip to content
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

Sync Passkey Easter egg on Passkey Details Touchpoint #45

Merged
merged 1 commit into from
Nov 22, 2023
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
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@trusona/touchpoint-sdk",
"version": "0.0.3",
"version": "0.0.4",
"repository": {
"type": "git",
"url": "git+https://github.com/trusona/auth-cloud-touchpoint-sdk.git"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,31 @@ export default {
layout: 'centered',
},
argTypes: {
savedText: {
description: "Text to indicate the Created Date"
},
lastUsedText: {
description: "Text to indicate the Last Used Date"
},
lastUsedIsMobile: {
description: "Boolean to indicate if the Last Usage was on Mobile",
table: {defaultValue: {summary: 'false'}}
},
prevLastUsedText: {
description: "[Optional] Text to indicate the Previous Last Used Date"
},
prevLastUsedIsMobile: {
description: "[Optional] Boolean to indicate if the Previous Last Usage was on Mobile",
table: {defaultValue: {summary: 'false'}}
passkeyDetails: {
description: `PasskeyDetails Object:

PasskeyDetails {
createdAt: string,
isSync: boolean,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kevin-villalobos-trusona is there a reason we didn't just use synced as the field name here?

I'm not sure if we need to bring is java-idioms to typescript.

createdOperatingSystem: string,
passkeyActivity: Array< PasskeyActivity >
}

PasskeyActivity {
lastUsedAt: string,
operatingSystem: string
}`,
control: {
type: 'object'
}
}
}
} as Meta


let passkeyDetails: PasskeyDetails = {
createdAt: '2023-10-12T17:12:13.183221Z',
isSync: true,
createdOperatingSystem: 'Mac OS',
passkeyActivity: [
{
Expand Down
123 changes: 61 additions & 62 deletions src/components/fido-passkey-details-card/fido-passkey-details-card.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {LitElement, html, css, TemplateResult} from 'lit'
import {customElement, property} from 'lit/decorators.js'
import {repeat} from 'lit/directives/repeat.js'
import {sharedStyles} from '../../shared/style'
import {DateTime} from 'luxon';
import { LitElement, html, css, TemplateResult } from 'lit'
import { customElement, property } from 'lit/decorators.js'
import { repeat } from 'lit/directives/repeat.js'
import { sharedStyles } from '../../shared/style'
import { DateTime } from 'luxon'

const componentStyle = css`

Expand Down Expand Up @@ -85,26 +85,25 @@ const componentStyle = css`
`

export interface PasskeyActivity {
lastUsedAt: string
operatingSystem: string
lastUsedAt: string
operatingSystem: string
}

export interface PasskeyDetails {
createdAt: string
createdOperatingSystem: string
passkeyActivity: Array<PasskeyActivity>
createdAt: string
isSync: boolean
createdOperatingSystem: string
passkeyActivity: PasskeyActivity[]
}

@customElement('fido-passkey-details-card')
class FidoPasskeyDetailsCard extends LitElement {
@property({ type: Object }) passkeyDetails?: PasskeyDetails

@property({type: Object}) passkeyDetails?: PasskeyDetails
static styles = [sharedStyles, componentStyle]

static styles = [sharedStyles, componentStyle]

render(): TemplateResult {
// console.log(this.passkeyDetails)
return html`
render (): TemplateResult {
return html`
<div class="auth-card">
<div class="auth-card-header">
<svg class="auth-img" viewBox="0 0 22 21" fill="none" xmlns="http://www.w3.org/2000/svg">
Expand Down Expand Up @@ -133,67 +132,67 @@ class FidoPasskeyDetailsCard extends LitElement {
</div>
</div>
`
}
}

private getCreatedAtText(): string {
const createdAt = this.passkeyDetails?.createdAt
const os = this.passkeyDetails?.createdOperatingSystem
const formattedDate = this.getFormattedDate(createdAt ?? "")
if (formattedDate) {
return `Saved with ${os ?? "--"} on ${formattedDate}`
} else {
return ""
}
private getCreatedAtText (): string {
const createdAt = this.passkeyDetails?.createdAt
const os = this.passkeyDetails?.createdOperatingSystem
const formattedDate = this.getFormattedDate(createdAt ?? '')
const syncText = this.passkeyDetails?.isSync === true ? '.' : ''
if (formattedDate) {
return `Saved with ${os ?? '--'} on ${formattedDate}${syncText}`
} else {
return ''
}
}

private getLastUsedAtText(lastUsedAt?: string, lastUsedOs?: String): string {
const formattedDate = this.getFormattedDate(lastUsedAt ?? "")
return `${lastUsedOs ?? ""}, ${formattedDate}`
}
private getLastUsedAtText (lastUsedAt?: string, lastUsedOs?: String): string {
const formattedDate = this.getFormattedDate(lastUsedAt ?? '')
return `${lastUsedOs ?? ''}, ${formattedDate}`
}

private getFormattedDate(date: string) {
const parsedDate = DateTime.fromISO(date);
if (parsedDate.isValid) {
return parsedDate.toFormat("MMM d, yyyy, h:mm a ZZZZ")
} else {
return ""
}
private getFormattedDate (date: string) {
const parsedDate = DateTime.fromISO(date)
if (parsedDate.isValid) {
return parsedDate.toFormat('MMM d, yyyy, h:mm a ZZZZ')
} else {
return ''
}
}

private getLastUsedActivity(): TemplateResult {
const activityList = this.passkeyDetails?.passkeyActivity
if (Array.isArray(activityList) && activityList.length > 0) {
return html`
private getLastUsedActivity (): TemplateResult {
const activityList = this.passkeyDetails?.passkeyActivity
if (Array.isArray(activityList) && activityList.length > 0) {
return html`
${repeat(this.passkeyDetails?.passkeyActivity ?? [], (activity: PasskeyActivity) => html`
${this.getActivityRow(activity)}
`)}`
} else {
return html`
} else {
return html`
${this.getActivityRow({
lastUsedAt: this.passkeyDetails?.createdAt ?? "",
operatingSystem: this.passkeyDetails?.createdOperatingSystem ?? ""
lastUsedAt: this.passkeyDetails?.createdAt ?? '',
operatingSystem: this.passkeyDetails?.createdOperatingSystem ?? ''
})}
`
}
}
}

private isMobile (operatingSystem?: string) {
return operatingSystem?.toLowerCase().includes('android') || operatingSystem?.toLowerCase().includes('ios')
}

private isMobile(operatingSystem?: string) {
return operatingSystem?.toLowerCase().includes('android') || operatingSystem?.toLowerCase().includes('ios')
}

private getActivityRow(activity: PasskeyActivity): TemplateResult {
return html`
private getActivityRow (activity: PasskeyActivity): TemplateResult {
return html`
<div class="auth-card-row">
${this.getIcon(this.isMobile(activity.operatingSystem) ?? false)}
<p class="auth-card-h3">${this.getLastUsedAtText(activity.lastUsedAt, activity.operatingSystem)}</p>
</div>
`
}
}

private getIcon(isMobile: boolean): TemplateResult {
if (isMobile) {
return html`
private getIcon (isMobile: boolean): TemplateResult {
if (isMobile) {
return html`
<svg class="passkey-type-img" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.6114 11.6851H4.38916" stroke="#444444" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M10.5003 1.7959H5.50027C4.88662 1.7959 4.38916 2.29336 4.38916 2.90701V13.4626C4.38916 14.0762 4.88662 14.5737 5.50027 14.5737H10.5003C11.1139 14.5737 11.6114 14.0762 11.6114 13.4626V2.90701C11.6114 2.29336 11.1139 1.7959 10.5003 1.7959Z"
Expand All @@ -202,8 +201,8 @@ class FidoPasskeyDetailsCard extends LitElement {
fill="#444444"/>
</svg>
`
} else {
return html`
} else {
return html`
<svg class="passkey-type-img" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_5534_164)">
<path d="M14.4995 9.68506V3.18506C14.4995 2.35173 13.8262 1.68506 12.9995 1.68506H2.99951C2.16618 1.68506 1.49951 2.35173 1.49951 3.18506V9.68506C1.49951 9.95839 1.71951 10.1851 1.99951 10.1851H13.9995C14.2728 10.1851 14.4995 9.95839 14.4995 9.68506ZM13.4995 9.68506L13.9995 9.18506H1.99951L2.49951 9.68506V3.18506C2.49951 2.90506 2.71951 2.68506 2.99951 2.68506H12.9995C13.2728 2.68506 13.4995 2.90506 13.4995 3.18506V9.68506Z"
Expand All @@ -220,12 +219,12 @@ class FidoPasskeyDetailsCard extends LitElement {
</defs>
</svg>
`
}
}
}
}

declare global {
interface HTMLElementTagNameMap {
'fido-passkey-details-card': FidoPasskeyDetailsCard
}
interface HTMLElementTagNameMap {
'fido-passkey-details-card': FidoPasskeyDetailsCard
}
}
18 changes: 12 additions & 6 deletions src/fido/fido-passkey-details/fido-passkey-details.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,27 @@ export default {
description: `Array of PasskeyDetails Objects.

PasskeyDetails {
savedText: string,
lastUsedText: string
lastUsedIsMobile: boolean
prevLastUsedText?: string | null
prevLastUsedIsMobile?: boolean | null
createdAt: string,
isSync: boolean,
createdOperatingSystem: string,
passkeyActivity: Array< PasskeyActivity >
}

PasskeyActivity {
lastUsedAt: string,
operatingSystem: string
}`,
control: {
type: 'object'
}
},
}
}
} as Meta

let passkeyDetails: PasskeyDetails[] = [
{
createdAt: '2023-10-12T17:12:13.183221Z',
isSync: true,
createdOperatingSystem: 'Mac OS',
passkeyActivity: [
{
Expand All @@ -43,6 +48,7 @@ let passkeyDetails: PasskeyDetails[] = [
]
}, {
createdAt: '2023-10-10T17:12:13.183221Z',
isSync: false,
createdOperatingSystem: 'Android 13'
},
{
Expand Down
32 changes: 16 additions & 16 deletions src/fido/fido-passkey-details/fido-passkey-details.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {LitElement, html, css, TemplateResult} from 'lit'
import {repeat} from 'lit/directives/repeat.js'
import {customElement, property} from 'lit/decorators.js'
import {sharedStyles} from '../../shared/style'
import {PasskeyDetails} from "../../components/fido-passkey-details-card/fido-passkey-details-card";
import { LitElement, html, css, TemplateResult } from 'lit'
import { repeat } from 'lit/directives/repeat.js'
import { customElement, property } from 'lit/decorators.js'
import { sharedStyles } from '../../shared/style'
import { PasskeyDetails } from '../../components/fido-passkey-details-card/fido-passkey-details-card'

const componentStyle = css`

Expand Down Expand Up @@ -57,12 +57,12 @@ const componentStyle = css`

@customElement('fido-passkey-details')
class FidoPasskeyDetails extends LitElement {
@property({type: Array}) passkeyDetails: PasskeyDetails[] = new Array<PasskeyDetails>()
@property({ type: Array }) passkeyDetails: PasskeyDetails[] = new Array<PasskeyDetails>()

static styles = [sharedStyles, componentStyle]
static styles = [sharedStyles, componentStyle]

render(): TemplateResult {
return html`
render (): TemplateResult {
return html`
<div class="auth-container">
<p class="auth-h1">Passkeys</p>
${this.getPasskeys()}
Expand All @@ -85,20 +85,20 @@ class FidoPasskeyDetails extends LitElement {
</div>
</div>
`
}
}

private getPasskeys(): TemplateResult {
return html`
private getPasskeys (): TemplateResult {
return html`
${repeat(this.passkeyDetails, (details: PasskeyDetails) => html`
<fido-passkey-details-card passkeyDetails="${JSON.stringify(details)}">
</fido-passkey-details-card>
`)}
`
}
}
}

declare global {
interface HTMLElementTagNameMap {
'fido-passkey-details': FidoPasskeyDetails
}
interface HTMLElementTagNameMap {
'fido-passkey-details': FidoPasskeyDetails
}
}
3 changes: 2 additions & 1 deletion testpages/components/fido-passkey-details-card.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Auth Cloud SDK Demo</title>
<script type="module" src="/dist/touchpoint-sdk.umd.js"></script>
<script type="module" src="../../dist/touchpoint-sdk.umd.cjs"></script>
<link rel="stylesheet" href="../styles.css">

<script>
const passkeyDetails = {
createdAt: '2023-10-12T17:12:13.183221Z',
isSync: true,
createdOperatingSystem: 'Mac OS',
passkeyActivity: [
{
Expand Down
4 changes: 3 additions & 1 deletion testpages/fido/fido-passkey-details.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Auth Cloud SDK Demo</title>
<script type="module" src="/dist/touchpoint-sdk.umd.js"></script>
<script type="module" src="../../dist/touchpoint-sdk.umd.cjs"></script>
<link rel="stylesheet" href="../styles.css">
<script>
const passkeyDetails = [
{
createdAt: '2023-10-12T17:12:13.183221Z',
createdOperatingSystem: 'Mac OS',
isSync: true,
passkeyActivity: [
{
lastUsedAt: '2023-10-13T17:12:13.183221Z',
Expand All @@ -23,6 +24,7 @@
]
}, {
createdAt: '2023-10-10T17:12:13.183221Z',
isSync: false,
createdOperatingSystem: 'Android 13'
},
{
Expand Down
Loading