From c707d9c02bab395141fb053bdcd7f26460cc7366 Mon Sep 17 00:00:00 2001 From: Jonathan Stewmon Date: Wed, 4 Nov 2020 08:45:40 -0600 Subject: chore: remove dom lib reference from server package The dom lib is incompatible with node, which can result in inaccurate type checking. Packages which reference types provided by a lib require package consumers to either include the lib or use skipLibCheck which disables all type declaration checks. So instead of referencing the dom lib, define the types needed by the server package locally and import them where needed. --- packages/typescript-types/src/dom.ts | 126 +++++++++++++++++++++++++++++++++ packages/typescript-types/src/index.ts | 15 ++++ 2 files changed, 141 insertions(+) create mode 100644 packages/typescript-types/src/dom.ts (limited to 'packages/typescript-types') diff --git a/packages/typescript-types/src/dom.ts b/packages/typescript-types/src/dom.ts new file mode 100644 index 0000000..8369427 --- /dev/null +++ b/packages/typescript-types/src/dom.ts @@ -0,0 +1,126 @@ +export interface txAuthGenericArg { + content: ArrayBuffer; + contentType: string; +} + +export interface AuthenticationExtensionsClientInputs { + appid?: string; + authnSel?: AuthenticatorSelectionList; + exts?: boolean; + loc?: boolean; + txAuthGeneric?: txAuthGenericArg; + txAuthSimple?: string; + uvi?: boolean; + uvm?: boolean; +} + +export interface AuthenticationExtensionsClientOutputs { + appid?: boolean; + authnSel?: boolean; + exts?: AuthenticationExtensionsSupported; + loc?: Coordinates; + txAuthGeneric?: ArrayBuffer; + txAuthSimple?: string; + uvi?: ArrayBuffer; + uvm?: UvmEntries; +} + +export interface AuthenticatorAssertionResponse extends AuthenticatorResponse { + readonly authenticatorData: ArrayBuffer; + readonly signature: ArrayBuffer; + readonly userHandle: ArrayBuffer | null; +} + +export interface AuthenticatorAttestationResponse extends AuthenticatorResponse { + readonly attestationObject: ArrayBuffer; +} + +export interface AuthenticatorResponse { + readonly clientDataJSON: ArrayBuffer; +} + +export interface AuthenticatorSelectionCriteria { + authenticatorAttachment?: AuthenticatorAttachment; + requireResidentKey?: boolean; + userVerification?: UserVerificationRequirement; +} + +export interface Coordinates { + readonly accuracy: number; + readonly altitude: number | null; + readonly altitudeAccuracy: number | null; + readonly heading: number | null; + readonly latitude: number; + readonly longitude: number; + readonly speed: number | null; +} + +export interface Credential { + readonly id: string; + readonly type: string; +} + +export interface PublicKeyCredential extends Credential { + readonly rawId: ArrayBuffer; + readonly response: AuthenticatorResponse; + getClientExtensionResults(): AuthenticationExtensionsClientOutputs; +} + +export interface PublicKeyCredentialCreationOptions { + attestation?: AttestationConveyancePreference; + authenticatorSelection?: AuthenticatorSelectionCriteria; + challenge: BufferSource; + excludeCredentials?: PublicKeyCredentialDescriptor[]; + extensions?: AuthenticationExtensionsClientInputs; + pubKeyCredParams: PublicKeyCredentialParameters[]; + rp: PublicKeyCredentialRpEntity; + timeout?: number; + user: PublicKeyCredentialUserEntity; +} + +export interface PublicKeyCredentialDescriptor { + id: BufferSource; + transports?: AuthenticatorTransport[]; + type: PublicKeyCredentialType; +} + +export interface PublicKeyCredentialEntity { + icon?: string; + name: string; +} + +export interface PublicKeyCredentialParameters { + alg: COSEAlgorithmIdentifier; + type: PublicKeyCredentialType; +} + +export interface PublicKeyCredentialRequestOptions { + allowCredentials?: PublicKeyCredentialDescriptor[]; + challenge: BufferSource; + extensions?: AuthenticationExtensionsClientInputs; + rpId?: string; + timeout?: number; + userVerification?: UserVerificationRequirement; +} + +export interface PublicKeyCredentialRpEntity extends PublicKeyCredentialEntity { + id?: string; +} + +export interface PublicKeyCredentialUserEntity extends PublicKeyCredentialEntity { + displayName: string; + id: BufferSource; +} + +export type AAGUID = BufferSource; +export type AttestationConveyancePreference = 'direct' | 'indirect' | 'none'; +export type AuthenticationExtensionsSupported = string[]; +export type AuthenticatorAttachment = 'cross-platform' | 'platform'; +export type AuthenticatorSelectionList = AAGUID[]; +export type AuthenticatorTransport = 'ble' | 'internal' | 'nfc' | 'usb'; +export type BufferSource = ArrayBuffer | ArrayBufferView; +export type COSEAlgorithmIdentifier = number; +export type PublicKeyCredentialType = 'public-key'; +export type UserVerificationRequirement = 'discouraged' | 'preferred' | 'required'; +export type UvmEntry = number[]; +export type UvmEntries = UvmEntry[]; diff --git a/packages/typescript-types/src/index.ts b/packages/typescript-types/src/index.ts index 4f238d7..954615b 100644 --- a/packages/typescript-types/src/index.ts +++ b/packages/typescript-types/src/index.ts @@ -2,6 +2,21 @@ * @packageDocumentation * @module @simplewebauthn/typescript-types */ + +import type { + AuthenticatorAssertionResponse, + AuthenticatorAttestationResponse, + AuthenticatorTransport, + COSEAlgorithmIdentifier, + PublicKeyCredential, + PublicKeyCredentialCreationOptions, + PublicKeyCredentialDescriptor, + PublicKeyCredentialRequestOptions, + PublicKeyCredentialUserEntity, +} from './dom'; + +export * from './dom'; + /** * A variant of PublicKeyCredentialCreationOptions suitable for JSON transmission to the browser to * (eventually) get passed into navigator.credentials.create(...) in the browser. -- cgit v1.2.3 From 4bdcd1d13ae7127fa541b5cbef03b57355db5819 Mon Sep 17 00:00:00 2001 From: Jonathan Stewmon Date: Tue, 24 Nov 2020 17:09:35 -0600 Subject: build: extract-dom-types script to generate dom.ts --- package.json | 1 + packages/typescript-types/extract-dom-types.ts | 82 +++++++++++++++++ packages/typescript-types/package.json | 1 + packages/typescript-types/src/dom.ts | 120 +++++++++++++------------ packages/typescript-types/tsconfig.json | 6 +- 5 files changed, 150 insertions(+), 60 deletions(-) create mode 100644 packages/typescript-types/extract-dom-types.ts (limited to 'packages/typescript-types') diff --git a/package.json b/package.json index 0d38e01..5a6e1c9 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "rimraf": "^3.0.2", "semver": "^7.3.2", "ts-jest": "^25.5.1", + "ts-morph": "^9.0.0", "ts-node": "^8.10.2", "ttypescript": "^1.5.12", "typedoc": "^0.20.0-beta.8", diff --git a/packages/typescript-types/extract-dom-types.ts b/packages/typescript-types/extract-dom-types.ts new file mode 100644 index 0000000..bc16554 --- /dev/null +++ b/packages/typescript-types/extract-dom-types.ts @@ -0,0 +1,82 @@ +// n.b. ts-morph is a sibling devDependency of typescript, so that the module +// loader will resolve our project's typescript package, not the transient +// dependency of ts-morph. We only want to reference our typescript dependency +// for its version and its lib.dom.d.ts file. If any typescript functionality +// is needed, use import { ts } from "ts-morph"; +import { + InterfaceDeclaration, + Node, + Project, + Structure, + SyntaxKind, + TypeAliasDeclaration, +} from 'ts-morph'; +import { version } from 'typescript'; + +// List of types we directly reference from the dom lib. Only interface and type +// alias identifiers are valid, since other syntax types (class, function, var) +// are implementations, which will not be available outside of the browser. +const types = [ + 'AuthenticatorAssertionResponse', + 'AttestationConveyancePreference', + 'AuthenticatorAttestationResponse', + 'AuthenticatorTransport', + 'AuthenticationExtensionsClientInputs', + 'AuthenticatorSelectionCriteria', + 'COSEAlgorithmIdentifier', + 'PublicKeyCredential', + 'PublicKeyCredentialCreationOptions', + 'PublicKeyCredentialDescriptor', + 'PublicKeyCredentialParameters', + 'PublicKeyCredentialRequestOptions', + 'PublicKeyCredentialUserEntity', + 'UserVerificationRequirement', +]; + +const project = new Project({ skipAddingFilesFromTsConfig: true }); +const domSourcePath = 'typescript/lib/lib.dom.d.ts'; +const domSourceFile = project.addSourceFileAtPath(require.resolve(domSourcePath)); +const resolvedNodes = new Set(); +const unresolvedNodes = new Set( + types.map(type => { + const node = domSourceFile.getInterface(type) ?? domSourceFile.getTypeAlias(type); + if (!node) { + throw new Error(`${type} does not refer to an interface or type alias`); + } + return node; + }), +); + +while (unresolvedNodes.size > 0) { + for (const node of unresolvedNodes.values()) { + unresolvedNodes.delete(node); + resolvedNodes.add(node); + + // Declarations in lib files are never exported because they are globally + // available. Since we are extracting the types to a module, we export them. + node.setIsExported(true); + + // Find all descendant identifiers which reference an interface or type + // alias, and add them to the unresolved list. + for (const id of node.getDescendantsOfKind(SyntaxKind.Identifier)) { + for (const dn of id.getDefinitionNodes()) { + if (Node.isInterfaceDeclaration(dn) || Node.isTypeAliasDeclaration(dn)) { + if (!resolvedNodes.has(dn)) { + unresolvedNodes.add(dn); + } + } + } + } + } +} + +const outputSourceFile = project.createSourceFile(`src/dom.ts`, undefined, { overwrite: true }); +outputSourceFile.addStatements([ + `// Generated from typescript@${version} ${domSourcePath}`, + `// To regenerate, run the following command from the project root:`, + `// npx lerna --scope=@simplewebauthn/typescript-types exec -- npm run extract-dom-types`, +]); +const resolvedStructures = Array.from(resolvedNodes).map(node => node.getStructure()); +outputSourceFile.addInterfaces(resolvedStructures.filter(Structure.isInterface)); +outputSourceFile.addTypeAliases(resolvedStructures.filter(Structure.isTypeAlias)); +outputSourceFile.saveSync(); diff --git a/packages/typescript-types/package.json b/packages/typescript-types/package.json index 4a42c95..cd361a7 100644 --- a/packages/typescript-types/package.json +++ b/packages/typescript-types/package.json @@ -17,6 +17,7 @@ }, "scripts": { "build": "rimraf dist && tsc", + "extract-dom-types": "ts-node extract-dom-types.ts", "prepublish": "npm run build" }, "keywords": [ diff --git a/packages/typescript-types/src/dom.ts b/packages/typescript-types/src/dom.ts index 8369427..6ec8148 100644 --- a/packages/typescript-types/src/dom.ts +++ b/packages/typescript-types/src/dom.ts @@ -1,6 +1,14 @@ -export interface txAuthGenericArg { - content: ArrayBuffer; - contentType: string; +// Generated from typescript@3.9.7 typescript/lib/lib.dom.d.ts +// To regenerate, run the following command from the project root: +// npx lerna --scope=@simplewebauthn/typescript-types exec -- npm run extract-dom-types +export interface AuthenticatorAssertionResponse extends AuthenticatorResponse { + readonly authenticatorData: ArrayBuffer; + readonly signature: ArrayBuffer; + readonly userHandle: ArrayBuffer | null; +} + +export interface AuthenticatorAttestationResponse extends AuthenticatorResponse { + readonly attestationObject: ArrayBuffer; } export interface AuthenticationExtensionsClientInputs { @@ -14,52 +22,12 @@ export interface AuthenticationExtensionsClientInputs { uvm?: boolean; } -export interface AuthenticationExtensionsClientOutputs { - appid?: boolean; - authnSel?: boolean; - exts?: AuthenticationExtensionsSupported; - loc?: Coordinates; - txAuthGeneric?: ArrayBuffer; - txAuthSimple?: string; - uvi?: ArrayBuffer; - uvm?: UvmEntries; -} - -export interface AuthenticatorAssertionResponse extends AuthenticatorResponse { - readonly authenticatorData: ArrayBuffer; - readonly signature: ArrayBuffer; - readonly userHandle: ArrayBuffer | null; -} - -export interface AuthenticatorAttestationResponse extends AuthenticatorResponse { - readonly attestationObject: ArrayBuffer; -} - -export interface AuthenticatorResponse { - readonly clientDataJSON: ArrayBuffer; -} - export interface AuthenticatorSelectionCriteria { authenticatorAttachment?: AuthenticatorAttachment; requireResidentKey?: boolean; userVerification?: UserVerificationRequirement; } -export interface Coordinates { - readonly accuracy: number; - readonly altitude: number | null; - readonly altitudeAccuracy: number | null; - readonly heading: number | null; - readonly latitude: number; - readonly longitude: number; - readonly speed: number | null; -} - -export interface Credential { - readonly id: string; - readonly type: string; -} - export interface PublicKeyCredential extends Credential { readonly rawId: ArrayBuffer; readonly response: AuthenticatorResponse; @@ -84,11 +52,6 @@ export interface PublicKeyCredentialDescriptor { type: PublicKeyCredentialType; } -export interface PublicKeyCredentialEntity { - icon?: string; - name: string; -} - export interface PublicKeyCredentialParameters { alg: COSEAlgorithmIdentifier; type: PublicKeyCredentialType; @@ -103,24 +66,65 @@ export interface PublicKeyCredentialRequestOptions { userVerification?: UserVerificationRequirement; } +export interface PublicKeyCredentialUserEntity extends PublicKeyCredentialEntity { + displayName: string; + id: BufferSource; +} + +export interface AuthenticatorResponse { + readonly clientDataJSON: ArrayBuffer; +} + +export interface txAuthGenericArg { + content: ArrayBuffer; + contentType: string; +} + +export interface Credential { + readonly id: string; + readonly type: string; +} + +export interface AuthenticationExtensionsClientOutputs { + appid?: boolean; + authnSel?: boolean; + exts?: AuthenticationExtensionsSupported; + loc?: Coordinates; + txAuthGeneric?: ArrayBuffer; + txAuthSimple?: string; + uvi?: ArrayBuffer; + uvm?: UvmEntries; +} + export interface PublicKeyCredentialRpEntity extends PublicKeyCredentialEntity { id?: string; } -export interface PublicKeyCredentialUserEntity extends PublicKeyCredentialEntity { - displayName: string; - id: BufferSource; +export interface PublicKeyCredentialEntity { + icon?: string; + name: string; +} + +/** The position and altitude of the device on Earth, as well as the accuracy with which these properties are calculated. */ +export interface Coordinates { + readonly accuracy: number; + readonly altitude: number | null; + readonly altitudeAccuracy: number | null; + readonly heading: number | null; + readonly latitude: number; + readonly longitude: number; + readonly speed: number | null; } -export type AAGUID = BufferSource; export type AttestationConveyancePreference = 'direct' | 'indirect' | 'none'; -export type AuthenticationExtensionsSupported = string[]; -export type AuthenticatorAttachment = 'cross-platform' | 'platform'; -export type AuthenticatorSelectionList = AAGUID[]; export type AuthenticatorTransport = 'ble' | 'internal' | 'nfc' | 'usb'; -export type BufferSource = ArrayBuffer | ArrayBufferView; export type COSEAlgorithmIdentifier = number; -export type PublicKeyCredentialType = 'public-key'; export type UserVerificationRequirement = 'discouraged' | 'preferred' | 'required'; -export type UvmEntry = number[]; +export type AuthenticatorSelectionList = AAGUID[]; +export type AuthenticatorAttachment = 'cross-platform' | 'platform'; +export type BufferSource = ArrayBufferView | ArrayBuffer; +export type PublicKeyCredentialType = 'public-key'; +export type AAGUID = BufferSource; +export type AuthenticationExtensionsSupported = string[]; export type UvmEntries = UvmEntry[]; +export type UvmEntry = number[]; diff --git a/packages/typescript-types/tsconfig.json b/packages/typescript-types/tsconfig.json index 349e40c..6dfff5f 100644 --- a/packages/typescript-types/tsconfig.json +++ b/packages/typescript-types/tsconfig.json @@ -2,6 +2,8 @@ "extends": "../../tsconfig.json", "compilerOptions": { "baseUrl": "./src", - "outDir": "./dist" - } + "outDir": "./dist", + "emitDeclarationOnly": true + }, + "include": ["src/**/*"] } -- cgit v1.2.3 From dd5c803ce2914da49ad5f9462c05b49026c6c377 Mon Sep 17 00:00:00 2001 From: Jonathan Stewmon Date: Thu, 26 Nov 2020 11:05:23 -0600 Subject: chore(typescript-types): always generate dom.ts --- .gitignore | 1 + packages/typescript-types/package.json | 2 +- packages/typescript-types/src/dom.ts | 130 --------------------------------- 3 files changed, 2 insertions(+), 131 deletions(-) delete mode 100644 packages/typescript-types/src/dom.ts (limited to 'packages/typescript-types') diff --git a/.gitignore b/.gitignore index ab333ee..3db653e 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ example/*.crt example/fido-conformance-mds/* !example/fido-conformance-mds/.gitkeep package-lock.json +packages/typescript-types/src/dom.ts diff --git a/packages/typescript-types/package.json b/packages/typescript-types/package.json index cd361a7..a05db68 100644 --- a/packages/typescript-types/package.json +++ b/packages/typescript-types/package.json @@ -16,7 +16,7 @@ "access": "public" }, "scripts": { - "build": "rimraf dist && tsc", + "build": "rimraf dist && npm run extract-dom-types && tsc", "extract-dom-types": "ts-node extract-dom-types.ts", "prepublish": "npm run build" }, diff --git a/packages/typescript-types/src/dom.ts b/packages/typescript-types/src/dom.ts deleted file mode 100644 index 6ec8148..0000000 --- a/packages/typescript-types/src/dom.ts +++ /dev/null @@ -1,130 +0,0 @@ -// Generated from typescript@3.9.7 typescript/lib/lib.dom.d.ts -// To regenerate, run the following command from the project root: -// npx lerna --scope=@simplewebauthn/typescript-types exec -- npm run extract-dom-types -export interface AuthenticatorAssertionResponse extends AuthenticatorResponse { - readonly authenticatorData: ArrayBuffer; - readonly signature: ArrayBuffer; - readonly userHandle: ArrayBuffer | null; -} - -export interface AuthenticatorAttestationResponse extends AuthenticatorResponse { - readonly attestationObject: ArrayBuffer; -} - -export interface AuthenticationExtensionsClientInputs { - appid?: string; - authnSel?: AuthenticatorSelectionList; - exts?: boolean; - loc?: boolean; - txAuthGeneric?: txAuthGenericArg; - txAuthSimple?: string; - uvi?: boolean; - uvm?: boolean; -} - -export interface AuthenticatorSelectionCriteria { - authenticatorAttachment?: AuthenticatorAttachment; - requireResidentKey?: boolean; - userVerification?: UserVerificationRequirement; -} - -export interface PublicKeyCredential extends Credential { - readonly rawId: ArrayBuffer; - readonly response: AuthenticatorResponse; - getClientExtensionResults(): AuthenticationExtensionsClientOutputs; -} - -export interface PublicKeyCredentialCreationOptions { - attestation?: AttestationConveyancePreference; - authenticatorSelection?: AuthenticatorSelectionCriteria; - challenge: BufferSource; - excludeCredentials?: PublicKeyCredentialDescriptor[]; - extensions?: AuthenticationExtensionsClientInputs; - pubKeyCredParams: PublicKeyCredentialParameters[]; - rp: PublicKeyCredentialRpEntity; - timeout?: number; - user: PublicKeyCredentialUserEntity; -} - -export interface PublicKeyCredentialDescriptor { - id: BufferSource; - transports?: AuthenticatorTransport[]; - type: PublicKeyCredentialType; -} - -export interface PublicKeyCredentialParameters { - alg: COSEAlgorithmIdentifier; - type: PublicKeyCredentialType; -} - -export interface PublicKeyCredentialRequestOptions { - allowCredentials?: PublicKeyCredentialDescriptor[]; - challenge: BufferSource; - extensions?: AuthenticationExtensionsClientInputs; - rpId?: string; - timeout?: number; - userVerification?: UserVerificationRequirement; -} - -export interface PublicKeyCredentialUserEntity extends PublicKeyCredentialEntity { - displayName: string; - id: BufferSource; -} - -export interface AuthenticatorResponse { - readonly clientDataJSON: ArrayBuffer; -} - -export interface txAuthGenericArg { - content: ArrayBuffer; - contentType: string; -} - -export interface Credential { - readonly id: string; - readonly type: string; -} - -export interface AuthenticationExtensionsClientOutputs { - appid?: boolean; - authnSel?: boolean; - exts?: AuthenticationExtensionsSupported; - loc?: Coordinates; - txAuthGeneric?: ArrayBuffer; - txAuthSimple?: string; - uvi?: ArrayBuffer; - uvm?: UvmEntries; -} - -export interface PublicKeyCredentialRpEntity extends PublicKeyCredentialEntity { - id?: string; -} - -export interface PublicKeyCredentialEntity { - icon?: string; - name: string; -} - -/** The position and altitude of the device on Earth, as well as the accuracy with which these properties are calculated. */ -export interface Coordinates { - readonly accuracy: number; - readonly altitude: number | null; - readonly altitudeAccuracy: number | null; - readonly heading: number | null; - readonly latitude: number; - readonly longitude: number; - readonly speed: number | null; -} - -export type AttestationConveyancePreference = 'direct' | 'indirect' | 'none'; -export type AuthenticatorTransport = 'ble' | 'internal' | 'nfc' | 'usb'; -export type COSEAlgorithmIdentifier = number; -export type UserVerificationRequirement = 'discouraged' | 'preferred' | 'required'; -export type AuthenticatorSelectionList = AAGUID[]; -export type AuthenticatorAttachment = 'cross-platform' | 'platform'; -export type BufferSource = ArrayBufferView | ArrayBuffer; -export type PublicKeyCredentialType = 'public-key'; -export type AAGUID = BufferSource; -export type AuthenticationExtensionsSupported = string[]; -export type UvmEntries = UvmEntry[]; -export type UvmEntry = number[]; -- cgit v1.2.3