@capawesome/capacitor-passkeys 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/CapawesomeCapacitorPasskeys.podspec +17 -0
  2. package/LICENSE +21 -0
  3. package/Package.swift +28 -0
  4. package/README.md +472 -0
  5. package/android/build.gradle +61 -0
  6. package/android/src/main/AndroidManifest.xml +2 -0
  7. package/android/src/main/java/io/capawesome/capacitorjs/plugins/passkeys/Passkeys.java +173 -0
  8. package/android/src/main/java/io/capawesome/capacitorjs/plugins/passkeys/PasskeysPlugin.java +115 -0
  9. package/android/src/main/java/io/capawesome/capacitorjs/plugins/passkeys/classes/CustomException.java +20 -0
  10. package/android/src/main/java/io/capawesome/capacitorjs/plugins/passkeys/classes/CustomExceptions.java +12 -0
  11. package/android/src/main/java/io/capawesome/capacitorjs/plugins/passkeys/classes/options/CreatePasskeyOptions.java +38 -0
  12. package/android/src/main/java/io/capawesome/capacitorjs/plugins/passkeys/classes/options/GetPasskeyOptions.java +33 -0
  13. package/android/src/main/java/io/capawesome/capacitorjs/plugins/passkeys/classes/results/CreatePasskeyResult.java +22 -0
  14. package/android/src/main/java/io/capawesome/capacitorjs/plugins/passkeys/classes/results/GetPasskeyResult.java +22 -0
  15. package/android/src/main/java/io/capawesome/capacitorjs/plugins/passkeys/classes/results/IsAvailableResult.java +22 -0
  16. package/android/src/main/java/io/capawesome/capacitorjs/plugins/passkeys/interfaces/Callback.java +5 -0
  17. package/android/src/main/java/io/capawesome/capacitorjs/plugins/passkeys/interfaces/NonEmptyResultCallback.java +7 -0
  18. package/android/src/main/java/io/capawesome/capacitorjs/plugins/passkeys/interfaces/Result.java +7 -0
  19. package/android/src/main/res/.gitkeep +0 -0
  20. package/dist/docs.json +1091 -0
  21. package/dist/esm/definitions.d.ts +567 -0
  22. package/dist/esm/definitions.js +47 -0
  23. package/dist/esm/definitions.js.map +1 -0
  24. package/dist/esm/index.d.ts +4 -0
  25. package/dist/esm/index.js +7 -0
  26. package/dist/esm/index.js.map +1 -0
  27. package/dist/esm/web.d.ts +18 -0
  28. package/dist/esm/web.js +184 -0
  29. package/dist/esm/web.js.map +1 -0
  30. package/dist/plugin.cjs.js +244 -0
  31. package/dist/plugin.cjs.js.map +1 -0
  32. package/dist/plugin.js +247 -0
  33. package/dist/plugin.js.map +1 -0
  34. package/ios/Plugin/Classes/Options/CreatePasskeyOptions.swift +81 -0
  35. package/ios/Plugin/Classes/Options/GetPasskeyOptions.swift +54 -0
  36. package/ios/Plugin/Classes/Results/CreatePasskeyResult.swift +28 -0
  37. package/ios/Plugin/Classes/Results/GetPasskeyResult.swift +34 -0
  38. package/ios/Plugin/Classes/Results/IsAvailableResult.swift +16 -0
  39. package/ios/Plugin/Enums/CustomError.swift +65 -0
  40. package/ios/Plugin/Info.plist +24 -0
  41. package/ios/Plugin/Passkeys.swift +118 -0
  42. package/ios/Plugin/PasskeysHelper.swift +20 -0
  43. package/ios/Plugin/PasskeysPlugin.swift +86 -0
  44. package/ios/Plugin/Protocols/Result.swift +5 -0
  45. package/package.json +91 -0
package/dist/plugin.js ADDED
@@ -0,0 +1,247 @@
1
+ var capacitorPasskeys = (function (exports, core) {
2
+ 'use strict';
3
+
4
+ /**
5
+ * @since 0.1.0
6
+ */
7
+ exports.ErrorCode = void 0;
8
+ (function (ErrorCode) {
9
+ /**
10
+ * The operation was canceled by the user.
11
+ *
12
+ * @since 0.1.0
13
+ */
14
+ ErrorCode["Canceled"] = "CANCELED";
15
+ /**
16
+ * The passkey could not be created.
17
+ *
18
+ * @since 0.1.0
19
+ */
20
+ ErrorCode["CreateFailed"] = "CREATE_FAILED";
21
+ /**
22
+ * The app is not associated with the relying party domain.
23
+ *
24
+ * On **Android**, make sure that the Digital Asset Links file is set up
25
+ * correctly. On **iOS**, make sure that the Associated Domains
26
+ * entitlement is set up correctly.
27
+ *
28
+ * @since 0.1.0
29
+ */
30
+ ErrorCode["DomainNotAssociated"] = "DOMAIN_NOT_ASSOCIATED";
31
+ /**
32
+ * The passkey could not be retrieved.
33
+ *
34
+ * @since 0.1.0
35
+ */
36
+ ErrorCode["GetFailed"] = "GET_FAILED";
37
+ /**
38
+ * No matching passkey was found.
39
+ *
40
+ * @since 0.1.0
41
+ */
42
+ ErrorCode["NoCredential"] = "NO_CREDENTIAL";
43
+ /**
44
+ * Passkeys are not supported on this device.
45
+ *
46
+ * @since 0.1.0
47
+ */
48
+ ErrorCode["NotSupported"] = "NOT_SUPPORTED";
49
+ })(exports.ErrorCode || (exports.ErrorCode = {}));
50
+
51
+ const Passkeys = core.registerPlugin('Passkeys', {
52
+ web: () => Promise.resolve().then(function () { return web; }).then(m => new m.PasskeysWeb()),
53
+ });
54
+
55
+ class PasskeysWeb extends core.WebPlugin {
56
+ async createPasskey(options) {
57
+ if (!PasskeysWeb.isWebAuthnSupported()) {
58
+ throw PasskeysWeb.createNotSupportedException();
59
+ }
60
+ let credential;
61
+ try {
62
+ credential = await navigator.credentials.create({
63
+ publicKey: PasskeysWeb.parseCreationOptions(options),
64
+ });
65
+ }
66
+ catch (error) {
67
+ throw PasskeysWeb.createException(error, exports.ErrorCode.CreateFailed);
68
+ }
69
+ if (!(credential instanceof PublicKeyCredential)) {
70
+ throw new core.CapacitorException(PasskeysWeb.errorCreateFailed, undefined, {
71
+ code: exports.ErrorCode.CreateFailed,
72
+ });
73
+ }
74
+ return PasskeysWeb.serializeCredential(credential);
75
+ }
76
+ async getPasskey(options) {
77
+ if (!PasskeysWeb.isWebAuthnSupported()) {
78
+ throw PasskeysWeb.createNotSupportedException();
79
+ }
80
+ let credential;
81
+ try {
82
+ credential = await navigator.credentials.get({
83
+ publicKey: PasskeysWeb.parseRequestOptions(options),
84
+ });
85
+ }
86
+ catch (error) {
87
+ throw PasskeysWeb.createException(error, exports.ErrorCode.GetFailed);
88
+ }
89
+ if (!(credential instanceof PublicKeyCredential)) {
90
+ throw new core.CapacitorException(PasskeysWeb.errorGetFailed, undefined, {
91
+ code: exports.ErrorCode.GetFailed,
92
+ });
93
+ }
94
+ return PasskeysWeb.serializeCredential(credential);
95
+ }
96
+ async isAvailable() {
97
+ if (!PasskeysWeb.isWebAuthnSupported()) {
98
+ return { available: false };
99
+ }
100
+ const available = await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();
101
+ return { available };
102
+ }
103
+ static arrayBufferToBase64Url(buffer) {
104
+ const bytes = new Uint8Array(buffer);
105
+ let binary = '';
106
+ for (const byte of bytes) {
107
+ binary += String.fromCharCode(byte);
108
+ }
109
+ return btoa(binary)
110
+ .replace(/\+/g, '-')
111
+ .replace(/\//g, '_')
112
+ .replace(/=+$/, '');
113
+ }
114
+ static base64UrlToArrayBuffer(value) {
115
+ let base64 = value.replace(/-/g, '+').replace(/_/g, '/');
116
+ while (base64.length % 4 > 0) {
117
+ base64 += '=';
118
+ }
119
+ const binary = atob(base64);
120
+ const bytes = new Uint8Array(binary.length);
121
+ for (let index = 0; index < binary.length; index++) {
122
+ bytes[index] = binary.charCodeAt(index);
123
+ }
124
+ return bytes.buffer;
125
+ }
126
+ static createException(error, fallbackCode) {
127
+ let code = fallbackCode;
128
+ if (error instanceof DOMException) {
129
+ if (error.name === 'NotAllowedError') {
130
+ code = exports.ErrorCode.Canceled;
131
+ }
132
+ else if (error.name === 'SecurityError') {
133
+ code = exports.ErrorCode.DomainNotAssociated;
134
+ }
135
+ else if (error.name === 'NotSupportedError') {
136
+ code = exports.ErrorCode.NotSupported;
137
+ }
138
+ }
139
+ const message = error instanceof Error ? error.message : 'An unknown error has occurred.';
140
+ return new core.CapacitorException(message, undefined, { code });
141
+ }
142
+ static createNotSupportedException() {
143
+ return new core.CapacitorException(PasskeysWeb.errorNotSupported, undefined, {
144
+ code: exports.ErrorCode.NotSupported,
145
+ });
146
+ }
147
+ static isWebAuthnSupported() {
148
+ return (typeof window !== 'undefined' &&
149
+ typeof window.PublicKeyCredential !== 'undefined');
150
+ }
151
+ static parseCreationOptions(options) {
152
+ var _a;
153
+ if (typeof PublicKeyCredential.parseCreationOptionsFromJSON === 'function') {
154
+ return PublicKeyCredential.parseCreationOptionsFromJSON(options);
155
+ }
156
+ return {
157
+ attestation: options.attestation,
158
+ authenticatorSelection: options.authenticatorSelection,
159
+ challenge: PasskeysWeb.base64UrlToArrayBuffer(options.challenge),
160
+ excludeCredentials: (_a = options.excludeCredentials) === null || _a === void 0 ? void 0 : _a.map(credential => ({
161
+ id: PasskeysWeb.base64UrlToArrayBuffer(credential.id),
162
+ transports: credential.transports,
163
+ type: credential.type,
164
+ })),
165
+ pubKeyCredParams: options.pubKeyCredParams,
166
+ rp: options.rp,
167
+ timeout: options.timeout,
168
+ user: {
169
+ displayName: options.user.displayName,
170
+ id: PasskeysWeb.base64UrlToArrayBuffer(options.user.id),
171
+ name: options.user.name,
172
+ },
173
+ };
174
+ }
175
+ static parseRequestOptions(options) {
176
+ var _a;
177
+ if (typeof PublicKeyCredential.parseRequestOptionsFromJSON === 'function') {
178
+ return PublicKeyCredential.parseRequestOptionsFromJSON(options);
179
+ }
180
+ return {
181
+ allowCredentials: (_a = options.allowCredentials) === null || _a === void 0 ? void 0 : _a.map(credential => ({
182
+ id: PasskeysWeb.base64UrlToArrayBuffer(credential.id),
183
+ transports: credential.transports,
184
+ type: credential.type,
185
+ })),
186
+ challenge: PasskeysWeb.base64UrlToArrayBuffer(options.challenge),
187
+ rpId: options.rpId,
188
+ timeout: options.timeout,
189
+ userVerification: options.userVerification,
190
+ };
191
+ }
192
+ static serializeCredential(credential) {
193
+ var _a;
194
+ if (typeof credential.toJSON === 'function') {
195
+ return credential.toJSON();
196
+ }
197
+ const authenticatorAttachment = ((_a = credential.authenticatorAttachment) !== null && _a !== void 0 ? _a : undefined);
198
+ const id = credential.id;
199
+ const rawId = PasskeysWeb.arrayBufferToBase64Url(credential.rawId);
200
+ if (credential.response instanceof AuthenticatorAssertionResponse) {
201
+ const response = credential.response;
202
+ return {
203
+ authenticatorAttachment,
204
+ id,
205
+ rawId,
206
+ response: {
207
+ authenticatorData: PasskeysWeb.arrayBufferToBase64Url(response.authenticatorData),
208
+ clientDataJSON: PasskeysWeb.arrayBufferToBase64Url(response.clientDataJSON),
209
+ signature: PasskeysWeb.arrayBufferToBase64Url(response.signature),
210
+ userHandle: response.userHandle
211
+ ? PasskeysWeb.arrayBufferToBase64Url(response.userHandle)
212
+ : undefined,
213
+ },
214
+ type: 'public-key',
215
+ };
216
+ }
217
+ const response = credential.response;
218
+ return {
219
+ authenticatorAttachment,
220
+ id,
221
+ rawId,
222
+ response: {
223
+ attestationObject: PasskeysWeb.arrayBufferToBase64Url(response.attestationObject),
224
+ clientDataJSON: PasskeysWeb.arrayBufferToBase64Url(response.clientDataJSON),
225
+ transports: typeof response.getTransports === 'function'
226
+ ? response.getTransports()
227
+ : undefined,
228
+ },
229
+ type: 'public-key',
230
+ };
231
+ }
232
+ }
233
+ PasskeysWeb.errorCreateFailed = 'The passkey could not be created.';
234
+ PasskeysWeb.errorGetFailed = 'The passkey could not be retrieved.';
235
+ PasskeysWeb.errorNotSupported = 'Passkeys are not supported in this browser.';
236
+
237
+ var web = /*#__PURE__*/Object.freeze({
238
+ __proto__: null,
239
+ PasskeysWeb: PasskeysWeb
240
+ });
241
+
242
+ exports.Passkeys = Passkeys;
243
+
244
+ return exports;
245
+
246
+ })({}, capacitorExports);
247
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sources":["esm/definitions.js","esm/index.js","esm/web.js"],"sourcesContent":["/**\n * @since 0.1.0\n */\nexport var ErrorCode;\n(function (ErrorCode) {\n /**\n * The operation was canceled by the user.\n *\n * @since 0.1.0\n */\n ErrorCode[\"Canceled\"] = \"CANCELED\";\n /**\n * The passkey could not be created.\n *\n * @since 0.1.0\n */\n ErrorCode[\"CreateFailed\"] = \"CREATE_FAILED\";\n /**\n * The app is not associated with the relying party domain.\n *\n * On **Android**, make sure that the Digital Asset Links file is set up\n * correctly. On **iOS**, make sure that the Associated Domains\n * entitlement is set up correctly.\n *\n * @since 0.1.0\n */\n ErrorCode[\"DomainNotAssociated\"] = \"DOMAIN_NOT_ASSOCIATED\";\n /**\n * The passkey could not be retrieved.\n *\n * @since 0.1.0\n */\n ErrorCode[\"GetFailed\"] = \"GET_FAILED\";\n /**\n * No matching passkey was found.\n *\n * @since 0.1.0\n */\n ErrorCode[\"NoCredential\"] = \"NO_CREDENTIAL\";\n /**\n * Passkeys are not supported on this device.\n *\n * @since 0.1.0\n */\n ErrorCode[\"NotSupported\"] = \"NOT_SUPPORTED\";\n})(ErrorCode || (ErrorCode = {}));\n//# sourceMappingURL=definitions.js.map","import { registerPlugin } from '@capacitor/core';\nconst Passkeys = registerPlugin('Passkeys', {\n web: () => import('./web').then(m => new m.PasskeysWeb()),\n});\nexport * from './definitions';\nexport { Passkeys };\n//# sourceMappingURL=index.js.map","import { CapacitorException, WebPlugin } from '@capacitor/core';\nimport { ErrorCode } from './definitions';\nexport class PasskeysWeb extends WebPlugin {\n async createPasskey(options) {\n if (!PasskeysWeb.isWebAuthnSupported()) {\n throw PasskeysWeb.createNotSupportedException();\n }\n let credential;\n try {\n credential = await navigator.credentials.create({\n publicKey: PasskeysWeb.parseCreationOptions(options),\n });\n }\n catch (error) {\n throw PasskeysWeb.createException(error, ErrorCode.CreateFailed);\n }\n if (!(credential instanceof PublicKeyCredential)) {\n throw new CapacitorException(PasskeysWeb.errorCreateFailed, undefined, {\n code: ErrorCode.CreateFailed,\n });\n }\n return PasskeysWeb.serializeCredential(credential);\n }\n async getPasskey(options) {\n if (!PasskeysWeb.isWebAuthnSupported()) {\n throw PasskeysWeb.createNotSupportedException();\n }\n let credential;\n try {\n credential = await navigator.credentials.get({\n publicKey: PasskeysWeb.parseRequestOptions(options),\n });\n }\n catch (error) {\n throw PasskeysWeb.createException(error, ErrorCode.GetFailed);\n }\n if (!(credential instanceof PublicKeyCredential)) {\n throw new CapacitorException(PasskeysWeb.errorGetFailed, undefined, {\n code: ErrorCode.GetFailed,\n });\n }\n return PasskeysWeb.serializeCredential(credential);\n }\n async isAvailable() {\n if (!PasskeysWeb.isWebAuthnSupported()) {\n return { available: false };\n }\n const available = await PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();\n return { available };\n }\n static arrayBufferToBase64Url(buffer) {\n const bytes = new Uint8Array(buffer);\n let binary = '';\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary)\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=+$/, '');\n }\n static base64UrlToArrayBuffer(value) {\n let base64 = value.replace(/-/g, '+').replace(/_/g, '/');\n while (base64.length % 4 > 0) {\n base64 += '=';\n }\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index++) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes.buffer;\n }\n static createException(error, fallbackCode) {\n let code = fallbackCode;\n if (error instanceof DOMException) {\n if (error.name === 'NotAllowedError') {\n code = ErrorCode.Canceled;\n }\n else if (error.name === 'SecurityError') {\n code = ErrorCode.DomainNotAssociated;\n }\n else if (error.name === 'NotSupportedError') {\n code = ErrorCode.NotSupported;\n }\n }\n const message = error instanceof Error ? error.message : 'An unknown error has occurred.';\n return new CapacitorException(message, undefined, { code });\n }\n static createNotSupportedException() {\n return new CapacitorException(PasskeysWeb.errorNotSupported, undefined, {\n code: ErrorCode.NotSupported,\n });\n }\n static isWebAuthnSupported() {\n return (typeof window !== 'undefined' &&\n typeof window.PublicKeyCredential !== 'undefined');\n }\n static parseCreationOptions(options) {\n var _a;\n if (typeof PublicKeyCredential.parseCreationOptionsFromJSON === 'function') {\n return PublicKeyCredential.parseCreationOptionsFromJSON(options);\n }\n return {\n attestation: options.attestation,\n authenticatorSelection: options.authenticatorSelection,\n challenge: PasskeysWeb.base64UrlToArrayBuffer(options.challenge),\n excludeCredentials: (_a = options.excludeCredentials) === null || _a === void 0 ? void 0 : _a.map(credential => ({\n id: PasskeysWeb.base64UrlToArrayBuffer(credential.id),\n transports: credential.transports,\n type: credential.type,\n })),\n pubKeyCredParams: options.pubKeyCredParams,\n rp: options.rp,\n timeout: options.timeout,\n user: {\n displayName: options.user.displayName,\n id: PasskeysWeb.base64UrlToArrayBuffer(options.user.id),\n name: options.user.name,\n },\n };\n }\n static parseRequestOptions(options) {\n var _a;\n if (typeof PublicKeyCredential.parseRequestOptionsFromJSON === 'function') {\n return PublicKeyCredential.parseRequestOptionsFromJSON(options);\n }\n return {\n allowCredentials: (_a = options.allowCredentials) === null || _a === void 0 ? void 0 : _a.map(credential => ({\n id: PasskeysWeb.base64UrlToArrayBuffer(credential.id),\n transports: credential.transports,\n type: credential.type,\n })),\n challenge: PasskeysWeb.base64UrlToArrayBuffer(options.challenge),\n rpId: options.rpId,\n timeout: options.timeout,\n userVerification: options.userVerification,\n };\n }\n static serializeCredential(credential) {\n var _a;\n if (typeof credential.toJSON === 'function') {\n return credential.toJSON();\n }\n const authenticatorAttachment = ((_a = credential.authenticatorAttachment) !== null && _a !== void 0 ? _a : undefined);\n const id = credential.id;\n const rawId = PasskeysWeb.arrayBufferToBase64Url(credential.rawId);\n if (credential.response instanceof AuthenticatorAssertionResponse) {\n const response = credential.response;\n return {\n authenticatorAttachment,\n id,\n rawId,\n response: {\n authenticatorData: PasskeysWeb.arrayBufferToBase64Url(response.authenticatorData),\n clientDataJSON: PasskeysWeb.arrayBufferToBase64Url(response.clientDataJSON),\n signature: PasskeysWeb.arrayBufferToBase64Url(response.signature),\n userHandle: response.userHandle\n ? PasskeysWeb.arrayBufferToBase64Url(response.userHandle)\n : undefined,\n },\n type: 'public-key',\n };\n }\n const response = credential.response;\n return {\n authenticatorAttachment,\n id,\n rawId,\n response: {\n attestationObject: PasskeysWeb.arrayBufferToBase64Url(response.attestationObject),\n clientDataJSON: PasskeysWeb.arrayBufferToBase64Url(response.clientDataJSON),\n transports: typeof response.getTransports === 'function'\n ? response.getTransports()\n : undefined,\n },\n type: 'public-key',\n };\n }\n}\nPasskeysWeb.errorCreateFailed = 'The passkey could not be created.';\nPasskeysWeb.errorGetFailed = 'The passkey could not be retrieved.';\nPasskeysWeb.errorNotSupported = 'Passkeys are not supported in this browser.';\n//# sourceMappingURL=web.js.map"],"names":["ErrorCode","registerPlugin","WebPlugin","CapacitorException"],"mappings":";;;IAAA;IACA;IACA;AACWA;IACX,CAAC,UAAU,SAAS,EAAE;IACtB;IACA;IACA;IACA;IACA;IACA,IAAI,SAAS,CAAC,UAAU,CAAC,GAAG,UAAU;IACtC;IACA;IACA;IACA;IACA;IACA,IAAI,SAAS,CAAC,cAAc,CAAC,GAAG,eAAe;IAC/C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,IAAI,SAAS,CAAC,qBAAqB,CAAC,GAAG,uBAAuB;IAC9D;IACA;IACA;IACA;IACA;IACA,IAAI,SAAS,CAAC,WAAW,CAAC,GAAG,YAAY;IACzC;IACA;IACA;IACA;IACA;IACA,IAAI,SAAS,CAAC,cAAc,CAAC,GAAG,eAAe;IAC/C;IACA;IACA;IACA;IACA;IACA,IAAI,SAAS,CAAC,cAAc,CAAC,GAAG,eAAe;IAC/C,CAAC,EAAEA,iBAAS,KAAKA,iBAAS,GAAG,EAAE,CAAC,CAAC;;AC5C5B,UAAC,QAAQ,GAAGC,mBAAc,CAAC,UAAU,EAAE;IAC5C,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;IAC7D,CAAC;;ICDM,MAAM,WAAW,SAASC,cAAS,CAAC;IAC3C,IAAI,MAAM,aAAa,CAAC,OAAO,EAAE;IACjC,QAAQ,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,EAAE;IAChD,YAAY,MAAM,WAAW,CAAC,2BAA2B,EAAE;IAC3D,QAAQ;IACR,QAAQ,IAAI,UAAU;IACtB,QAAQ,IAAI;IACZ,YAAY,UAAU,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,MAAM,CAAC;IAC5D,gBAAgB,SAAS,EAAE,WAAW,CAAC,oBAAoB,CAAC,OAAO,CAAC;IACpE,aAAa,CAAC;IACd,QAAQ;IACR,QAAQ,OAAO,KAAK,EAAE;IACtB,YAAY,MAAM,WAAW,CAAC,eAAe,CAAC,KAAK,EAAEF,iBAAS,CAAC,YAAY,CAAC;IAC5E,QAAQ;IACR,QAAQ,IAAI,EAAE,UAAU,YAAY,mBAAmB,CAAC,EAAE;IAC1D,YAAY,MAAM,IAAIG,uBAAkB,CAAC,WAAW,CAAC,iBAAiB,EAAE,SAAS,EAAE;IACnF,gBAAgB,IAAI,EAAEH,iBAAS,CAAC,YAAY;IAC5C,aAAa,CAAC;IACd,QAAQ;IACR,QAAQ,OAAO,WAAW,CAAC,mBAAmB,CAAC,UAAU,CAAC;IAC1D,IAAI;IACJ,IAAI,MAAM,UAAU,CAAC,OAAO,EAAE;IAC9B,QAAQ,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,EAAE;IAChD,YAAY,MAAM,WAAW,CAAC,2BAA2B,EAAE;IAC3D,QAAQ;IACR,QAAQ,IAAI,UAAU;IACtB,QAAQ,IAAI;IACZ,YAAY,UAAU,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC;IACzD,gBAAgB,SAAS,EAAE,WAAW,CAAC,mBAAmB,CAAC,OAAO,CAAC;IACnE,aAAa,CAAC;IACd,QAAQ;IACR,QAAQ,OAAO,KAAK,EAAE;IACtB,YAAY,MAAM,WAAW,CAAC,eAAe,CAAC,KAAK,EAAEA,iBAAS,CAAC,SAAS,CAAC;IACzE,QAAQ;IACR,QAAQ,IAAI,EAAE,UAAU,YAAY,mBAAmB,CAAC,EAAE;IAC1D,YAAY,MAAM,IAAIG,uBAAkB,CAAC,WAAW,CAAC,cAAc,EAAE,SAAS,EAAE;IAChF,gBAAgB,IAAI,EAAEH,iBAAS,CAAC,SAAS;IACzC,aAAa,CAAC;IACd,QAAQ;IACR,QAAQ,OAAO,WAAW,CAAC,mBAAmB,CAAC,UAAU,CAAC;IAC1D,IAAI;IACJ,IAAI,MAAM,WAAW,GAAG;IACxB,QAAQ,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,EAAE;IAChD,YAAY,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE;IACvC,QAAQ;IACR,QAAQ,MAAM,SAAS,GAAG,MAAM,mBAAmB,CAAC,6CAA6C,EAAE;IACnG,QAAQ,OAAO,EAAE,SAAS,EAAE;IAC5B,IAAI;IACJ,IAAI,OAAO,sBAAsB,CAAC,MAAM,EAAE;IAC1C,QAAQ,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC;IAC5C,QAAQ,IAAI,MAAM,GAAG,EAAE;IACvB,QAAQ,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE;IAClC,YAAY,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC;IAC/C,QAAQ;IACR,QAAQ,OAAO,IAAI,CAAC,MAAM;IAC1B,aAAa,OAAO,CAAC,KAAK,EAAE,GAAG;IAC/B,aAAa,OAAO,CAAC,KAAK,EAAE,GAAG;IAC/B,aAAa,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;IAC/B,IAAI;IACJ,IAAI,OAAO,sBAAsB,CAAC,KAAK,EAAE;IACzC,QAAQ,IAAI,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;IAChE,QAAQ,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,EAAE;IACtC,YAAY,MAAM,IAAI,GAAG;IACzB,QAAQ;IACR,QAAQ,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IACnC,QAAQ,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC;IACnD,QAAQ,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;IAC5D,YAAY,KAAK,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC;IACnD,QAAQ;IACR,QAAQ,OAAO,KAAK,CAAC,MAAM;IAC3B,IAAI;IACJ,IAAI,OAAO,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE;IAChD,QAAQ,IAAI,IAAI,GAAG,YAAY;IAC/B,QAAQ,IAAI,KAAK,YAAY,YAAY,EAAE;IAC3C,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE;IAClD,gBAAgB,IAAI,GAAGA,iBAAS,CAAC,QAAQ;IACzC,YAAY;IACZ,iBAAiB,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE;IACrD,gBAAgB,IAAI,GAAGA,iBAAS,CAAC,mBAAmB;IACpD,YAAY;IACZ,iBAAiB,IAAI,KAAK,CAAC,IAAI,KAAK,mBAAmB,EAAE;IACzD,gBAAgB,IAAI,GAAGA,iBAAS,CAAC,YAAY;IAC7C,YAAY;IACZ,QAAQ;IACR,QAAQ,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,GAAG,KAAK,CAAC,OAAO,GAAG,gCAAgC;IACjG,QAAQ,OAAO,IAAIG,uBAAkB,CAAC,OAAO,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,CAAC;IACnE,IAAI;IACJ,IAAI,OAAO,2BAA2B,GAAG;IACzC,QAAQ,OAAO,IAAIA,uBAAkB,CAAC,WAAW,CAAC,iBAAiB,EAAE,SAAS,EAAE;IAChF,YAAY,IAAI,EAAEH,iBAAS,CAAC,YAAY;IACxC,SAAS,CAAC;IACV,IAAI;IACJ,IAAI,OAAO,mBAAmB,GAAG;IACjC,QAAQ,QAAQ,OAAO,MAAM,KAAK,WAAW;IAC7C,YAAY,OAAO,MAAM,CAAC,mBAAmB,KAAK,WAAW;IAC7D,IAAI;IACJ,IAAI,OAAO,oBAAoB,CAAC,OAAO,EAAE;IACzC,QAAQ,IAAI,EAAE;IACd,QAAQ,IAAI,OAAO,mBAAmB,CAAC,4BAA4B,KAAK,UAAU,EAAE;IACpF,YAAY,OAAO,mBAAmB,CAAC,4BAA4B,CAAC,OAAO,CAAC;IAC5E,QAAQ;IACR,QAAQ,OAAO;IACf,YAAY,WAAW,EAAE,OAAO,CAAC,WAAW;IAC5C,YAAY,sBAAsB,EAAE,OAAO,CAAC,sBAAsB;IAClE,YAAY,SAAS,EAAE,WAAW,CAAC,sBAAsB,CAAC,OAAO,CAAC,SAAS,CAAC;IAC5E,YAAY,kBAAkB,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,kBAAkB,MAAM,IAAI,IAAI,EAAE,KAAK,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK;IAC7H,gBAAgB,EAAE,EAAE,WAAW,CAAC,sBAAsB,CAAC,UAAU,CAAC,EAAE,CAAC;IACrE,gBAAgB,UAAU,EAAE,UAAU,CAAC,UAAU;IACjD,gBAAgB,IAAI,EAAE,UAAU,CAAC,IAAI;IACrC,aAAa,CAAC,CAAC;IACf,YAAY,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;IACtD,YAAY,EAAE,EAAE,OAAO,CAAC,EAAE;IAC1B,YAAY,OAAO,EAAE,OAAO,CAAC,OAAO;IACpC,YAAY,IAAI,EAAE;IAClB,gBAAgB,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,WAAW;IACrD,gBAAgB,EAAE,EAAE,WAAW,CAAC,sBAAsB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;IACvE,gBAAgB,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI;IACvC,aAAa;IACb,SAAS;IACT,IAAI;IACJ,IAAI,OAAO,mBAAmB,CAAC,OAAO,EAAE;IACxC,QAAQ,IAAI,EAAE;IACd,QAAQ,IAAI,OAAO,mBAAmB,CAAC,2BAA2B,KAAK,UAAU,EAAE;IACnF,YAAY,OAAO,mBAAmB,CAAC,2BAA2B,CAAC,OAAO,CAAC;IAC3E,QAAQ;IACR,QAAQ,OAAO;IACf,YAAY,gBAAgB,EAAE,CAAC,EAAE,GAAG,OAAO,CAAC,gBAAgB,MAAM,IAAI,IAAI,EAAE,KAAK,MAAM,GAAG,MAAM,GAAG,EAAE,CAAC,GAAG,CAAC,UAAU,KAAK;IACzH,gBAAgB,EAAE,EAAE,WAAW,CAAC,sBAAsB,CAAC,UAAU,CAAC,EAAE,CAAC;IACrE,gBAAgB,UAAU,EAAE,UAAU,CAAC,UAAU;IACjD,gBAAgB,IAAI,EAAE,UAAU,CAAC,IAAI;IACrC,aAAa,CAAC,CAAC;IACf,YAAY,SAAS,EAAE,WAAW,CAAC,sBAAsB,CAAC,OAAO,CAAC,SAAS,CAAC;IAC5E,YAAY,IAAI,EAAE,OAAO,CAAC,IAAI;IAC9B,YAAY,OAAO,EAAE,OAAO,CAAC,OAAO;IACpC,YAAY,gBAAgB,EAAE,OAAO,CAAC,gBAAgB;IACtD,SAAS;IACT,IAAI;IACJ,IAAI,OAAO,mBAAmB,CAAC,UAAU,EAAE;IAC3C,QAAQ,IAAI,EAAE;IACd,QAAQ,IAAI,OAAO,UAAU,CAAC,MAAM,KAAK,UAAU,EAAE;IACrD,YAAY,OAAO,UAAU,CAAC,MAAM,EAAE;IACtC,QAAQ;IACR,QAAQ,MAAM,uBAAuB,IAAI,CAAC,EAAE,GAAG,UAAU,CAAC,uBAAuB,MAAM,IAAI,IAAI,EAAE,KAAK,MAAM,GAAG,EAAE,GAAG,SAAS,CAAC;IAC9H,QAAQ,MAAM,EAAE,GAAG,UAAU,CAAC,EAAE;IAChC,QAAQ,MAAM,KAAK,GAAG,WAAW,CAAC,sBAAsB,CAAC,UAAU,CAAC,KAAK,CAAC;IAC1E,QAAQ,IAAI,UAAU,CAAC,QAAQ,YAAY,8BAA8B,EAAE;IAC3E,YAAY,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ;IAChD,YAAY,OAAO;IACnB,gBAAgB,uBAAuB;IACvC,gBAAgB,EAAE;IAClB,gBAAgB,KAAK;IACrB,gBAAgB,QAAQ,EAAE;IAC1B,oBAAoB,iBAAiB,EAAE,WAAW,CAAC,sBAAsB,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACrG,oBAAoB,cAAc,EAAE,WAAW,CAAC,sBAAsB,CAAC,QAAQ,CAAC,cAAc,CAAC;IAC/F,oBAAoB,SAAS,EAAE,WAAW,CAAC,sBAAsB,CAAC,QAAQ,CAAC,SAAS,CAAC;IACrF,oBAAoB,UAAU,EAAE,QAAQ,CAAC;IACzC,0BAA0B,WAAW,CAAC,sBAAsB,CAAC,QAAQ,CAAC,UAAU;IAChF,0BAA0B,SAAS;IACnC,iBAAiB;IACjB,gBAAgB,IAAI,EAAE,YAAY;IAClC,aAAa;IACb,QAAQ;IACR,QAAQ,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ;IAC5C,QAAQ,OAAO;IACf,YAAY,uBAAuB;IACnC,YAAY,EAAE;IACd,YAAY,KAAK;IACjB,YAAY,QAAQ,EAAE;IACtB,gBAAgB,iBAAiB,EAAE,WAAW,CAAC,sBAAsB,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACjG,gBAAgB,cAAc,EAAE,WAAW,CAAC,sBAAsB,CAAC,QAAQ,CAAC,cAAc,CAAC;IAC3F,gBAAgB,UAAU,EAAE,OAAO,QAAQ,CAAC,aAAa,KAAK;IAC9D,sBAAsB,QAAQ,CAAC,aAAa;IAC5C,sBAAsB,SAAS;IAC/B,aAAa;IACb,YAAY,IAAI,EAAE,YAAY;IAC9B,SAAS;IACT,IAAI;IACJ;IACA,WAAW,CAAC,iBAAiB,GAAG,mCAAmC;IACnE,WAAW,CAAC,cAAc,GAAG,qCAAqC;IAClE,WAAW,CAAC,iBAAiB,GAAG,6CAA6C;;;;;;;;;;;;;;;"}
@@ -0,0 +1,81 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ @objc public class CreatePasskeyOptions: NSObject {
5
+ let attestation: String?
6
+ let challenge: Data
7
+ let excludeCredentialIds: [Data]
8
+ let rpId: String
9
+ let userId: Data
10
+ let userName: String
11
+ let userVerification: String?
12
+
13
+ init(_ call: CAPPluginCall) throws {
14
+ self.attestation = CreatePasskeyOptions.getAttestationFromCall(call)
15
+ self.challenge = try CreatePasskeyOptions.getChallengeFromCall(call)
16
+ self.excludeCredentialIds = try CreatePasskeyOptions.getExcludeCredentialIdsFromCall(call)
17
+ self.rpId = try CreatePasskeyOptions.getRpIdFromCall(call)
18
+ self.userId = try CreatePasskeyOptions.getUserIdFromCall(call)
19
+ self.userName = try CreatePasskeyOptions.getUserNameFromCall(call)
20
+ self.userVerification = CreatePasskeyOptions.getUserVerificationFromCall(call)
21
+ }
22
+
23
+ private static func getAttestationFromCall(_ call: CAPPluginCall) -> String? {
24
+ return call.getString("attestation")
25
+ }
26
+
27
+ private static func getChallengeFromCall(_ call: CAPPluginCall) throws -> Data {
28
+ guard let challenge = call.getString("challenge") else {
29
+ throw CustomError.challengeMissing
30
+ }
31
+ guard let data = PasskeysHelper.dataFromBase64Url(challenge) else {
32
+ throw CustomError.challengeInvalid
33
+ }
34
+ return data
35
+ }
36
+
37
+ private static func getExcludeCredentialIdsFromCall(_ call: CAPPluginCall) throws -> [Data] {
38
+ guard let excludeCredentials = call.getArray("excludeCredentials") else {
39
+ return []
40
+ }
41
+ var ids: [Data] = []
42
+ for element in excludeCredentials {
43
+ guard let descriptor = element as? [String: Any], let id = descriptor["id"] as? String else {
44
+ continue
45
+ }
46
+ guard let data = PasskeysHelper.dataFromBase64Url(id) else {
47
+ throw CustomError.excludeCredentialsInvalid
48
+ }
49
+ ids.append(data)
50
+ }
51
+ return ids
52
+ }
53
+
54
+ private static func getRpIdFromCall(_ call: CAPPluginCall) throws -> String {
55
+ guard let rpId = call.getObject("rp")?["id"] as? String else {
56
+ throw CustomError.rpIdMissing
57
+ }
58
+ return rpId
59
+ }
60
+
61
+ private static func getUserIdFromCall(_ call: CAPPluginCall) throws -> Data {
62
+ guard let userId = call.getObject("user")?["id"] as? String else {
63
+ throw CustomError.userIdMissing
64
+ }
65
+ guard let data = PasskeysHelper.dataFromBase64Url(userId) else {
66
+ throw CustomError.userIdInvalid
67
+ }
68
+ return data
69
+ }
70
+
71
+ private static func getUserNameFromCall(_ call: CAPPluginCall) throws -> String {
72
+ guard let userName = call.getObject("user")?["name"] as? String else {
73
+ throw CustomError.userNameMissing
74
+ }
75
+ return userName
76
+ }
77
+
78
+ private static func getUserVerificationFromCall(_ call: CAPPluginCall) -> String? {
79
+ return call.getObject("authenticatorSelection")?["userVerification"] as? String
80
+ }
81
+ }
@@ -0,0 +1,54 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ @objc public class GetPasskeyOptions: NSObject {
5
+ let allowCredentialIds: [Data]
6
+ let challenge: Data
7
+ let rpId: String
8
+ let userVerification: String?
9
+
10
+ init(_ call: CAPPluginCall) throws {
11
+ self.allowCredentialIds = try GetPasskeyOptions.getAllowCredentialIdsFromCall(call)
12
+ self.challenge = try GetPasskeyOptions.getChallengeFromCall(call)
13
+ self.rpId = try GetPasskeyOptions.getRpIdFromCall(call)
14
+ self.userVerification = GetPasskeyOptions.getUserVerificationFromCall(call)
15
+ }
16
+
17
+ private static func getAllowCredentialIdsFromCall(_ call: CAPPluginCall) throws -> [Data] {
18
+ guard let allowCredentials = call.getArray("allowCredentials") else {
19
+ return []
20
+ }
21
+ var ids: [Data] = []
22
+ for element in allowCredentials {
23
+ guard let descriptor = element as? [String: Any], let id = descriptor["id"] as? String else {
24
+ continue
25
+ }
26
+ guard let data = PasskeysHelper.dataFromBase64Url(id) else {
27
+ throw CustomError.allowCredentialsInvalid
28
+ }
29
+ ids.append(data)
30
+ }
31
+ return ids
32
+ }
33
+
34
+ private static func getChallengeFromCall(_ call: CAPPluginCall) throws -> Data {
35
+ guard let challenge = call.getString("challenge") else {
36
+ throw CustomError.challengeMissing
37
+ }
38
+ guard let data = PasskeysHelper.dataFromBase64Url(challenge) else {
39
+ throw CustomError.challengeInvalid
40
+ }
41
+ return data
42
+ }
43
+
44
+ private static func getRpIdFromCall(_ call: CAPPluginCall) throws -> String {
45
+ guard let rpId = call.getString("rpId") else {
46
+ throw CustomError.rpIdTopLevelMissing
47
+ }
48
+ return rpId
49
+ }
50
+
51
+ private static func getUserVerificationFromCall(_ call: CAPPluginCall) -> String? {
52
+ return call.getString("userVerification")
53
+ }
54
+ }
@@ -0,0 +1,28 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ @objc public class CreatePasskeyResult: NSObject, Result {
5
+ let attestationObject: Data
6
+ let clientDataJSON: Data
7
+ let credentialId: Data
8
+
9
+ init(attestationObject: Data, clientDataJSON: Data, credentialId: Data) {
10
+ self.attestationObject = attestationObject
11
+ self.clientDataJSON = clientDataJSON
12
+ self.credentialId = credentialId
13
+ }
14
+
15
+ @objc public func toJSObject() -> AnyObject {
16
+ let credentialId = PasskeysHelper.base64UrlFromData(self.credentialId)
17
+ var response = JSObject()
18
+ response["attestationObject"] = PasskeysHelper.base64UrlFromData(attestationObject)
19
+ response["clientDataJSON"] = PasskeysHelper.base64UrlFromData(clientDataJSON)
20
+ var result = JSObject()
21
+ result["authenticatorAttachment"] = "platform"
22
+ result["id"] = credentialId
23
+ result["rawId"] = credentialId
24
+ result["response"] = response
25
+ result["type"] = "public-key"
26
+ return result as AnyObject
27
+ }
28
+ }
@@ -0,0 +1,34 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ @objc public class GetPasskeyResult: NSObject, Result {
5
+ let authenticatorData: Data
6
+ let clientDataJSON: Data
7
+ let credentialId: Data
8
+ let signature: Data
9
+ let userHandle: Data
10
+
11
+ init(authenticatorData: Data, clientDataJSON: Data, credentialId: Data, signature: Data, userHandle: Data) {
12
+ self.authenticatorData = authenticatorData
13
+ self.clientDataJSON = clientDataJSON
14
+ self.credentialId = credentialId
15
+ self.signature = signature
16
+ self.userHandle = userHandle
17
+ }
18
+
19
+ @objc public func toJSObject() -> AnyObject {
20
+ let credentialId = PasskeysHelper.base64UrlFromData(self.credentialId)
21
+ var response = JSObject()
22
+ response["authenticatorData"] = PasskeysHelper.base64UrlFromData(authenticatorData)
23
+ response["clientDataJSON"] = PasskeysHelper.base64UrlFromData(clientDataJSON)
24
+ response["signature"] = PasskeysHelper.base64UrlFromData(signature)
25
+ response["userHandle"] = PasskeysHelper.base64UrlFromData(userHandle)
26
+ var result = JSObject()
27
+ result["authenticatorAttachment"] = "platform"
28
+ result["id"] = credentialId
29
+ result["rawId"] = credentialId
30
+ result["response"] = response
31
+ result["type"] = "public-key"
32
+ return result as AnyObject
33
+ }
34
+ }
@@ -0,0 +1,16 @@
1
+ import Foundation
2
+ import Capacitor
3
+
4
+ @objc public class IsAvailableResult: NSObject, Result {
5
+ let available: Bool
6
+
7
+ init(available: Bool) {
8
+ self.available = available
9
+ }
10
+
11
+ @objc public func toJSObject() -> AnyObject {
12
+ var result = JSObject()
13
+ result["available"] = available
14
+ return result as AnyObject
15
+ }
16
+ }
@@ -0,0 +1,65 @@
1
+ import Foundation
2
+
3
+ public enum CustomError: Error {
4
+ case allowCredentialsInvalid
5
+ case canceled
6
+ case challengeInvalid
7
+ case challengeMissing
8
+ case createFailed
9
+ case domainNotAssociated
10
+ case excludeCredentialsInvalid
11
+ case getFailed
12
+ case rpIdMissing
13
+ case rpIdTopLevelMissing
14
+ case userIdInvalid
15
+ case userIdMissing
16
+ case userNameMissing
17
+
18
+ var code: String? {
19
+ switch self {
20
+ case .canceled:
21
+ return "CANCELED"
22
+ case .createFailed:
23
+ return "CREATE_FAILED"
24
+ case .domainNotAssociated:
25
+ return "DOMAIN_NOT_ASSOCIATED"
26
+ case .getFailed:
27
+ return "GET_FAILED"
28
+ default:
29
+ return nil
30
+ }
31
+ }
32
+ }
33
+
34
+ extension CustomError: LocalizedError {
35
+ public var errorDescription: String? {
36
+ switch self {
37
+ case .allowCredentialsInvalid:
38
+ return NSLocalizedString("allowCredentials contains an invalid id.", comment: "allowCredentialsInvalid")
39
+ case .canceled:
40
+ return NSLocalizedString("The operation was canceled by the user.", comment: "canceled")
41
+ case .challengeInvalid:
42
+ return NSLocalizedString("challenge must be a valid base64url-encoded string.", comment: "challengeInvalid")
43
+ case .challengeMissing:
44
+ return NSLocalizedString("challenge must be provided.", comment: "challengeMissing")
45
+ case .createFailed:
46
+ return NSLocalizedString("The passkey could not be created.", comment: "createFailed")
47
+ case .domainNotAssociated:
48
+ return NSLocalizedString("The app is not associated with the relying party domain.", comment: "domainNotAssociated")
49
+ case .excludeCredentialsInvalid:
50
+ return NSLocalizedString("excludeCredentials contains an invalid id.", comment: "excludeCredentialsInvalid")
51
+ case .getFailed:
52
+ return NSLocalizedString("The passkey could not be retrieved.", comment: "getFailed")
53
+ case .rpIdMissing:
54
+ return NSLocalizedString("rp.id must be provided.", comment: "rpIdMissing")
55
+ case .rpIdTopLevelMissing:
56
+ return NSLocalizedString("rpId must be provided.", comment: "rpIdTopLevelMissing")
57
+ case .userIdInvalid:
58
+ return NSLocalizedString("user.id must be a valid base64url-encoded string.", comment: "userIdInvalid")
59
+ case .userIdMissing:
60
+ return NSLocalizedString("user.id must be provided.", comment: "userIdMissing")
61
+ case .userNameMissing:
62
+ return NSLocalizedString("user.name must be provided.", comment: "userNameMissing")
63
+ }
64
+ }
65
+ }
@@ -0,0 +1,24 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>CFBundleDevelopmentRegion</key>
6
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
7
+ <key>CFBundleExecutable</key>
8
+ <string>$(EXECUTABLE_NAME)</string>
9
+ <key>CFBundleIdentifier</key>
10
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
11
+ <key>CFBundleInfoDictionaryVersion</key>
12
+ <string>6.0</string>
13
+ <key>CFBundleName</key>
14
+ <string>$(PRODUCT_NAME)</string>
15
+ <key>CFBundlePackageType</key>
16
+ <string>FMWK</string>
17
+ <key>CFBundleShortVersionString</key>
18
+ <string>1.0</string>
19
+ <key>CFBundleVersion</key>
20
+ <string>$(CURRENT_PROJECT_VERSION)</string>
21
+ <key>NSPrincipalClass</key>
22
+ <string></string>
23
+ </dict>
24
+ </plist>