@limrun/ui 0.9.0-rc.9 → 0.13.3

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 (80) hide show
  1. package/README.md +25 -8
  2. package/dist/app-store-relay/index.cjs +9 -0
  3. package/dist/app-store-relay/index.d.ts +102 -0
  4. package/dist/app-store-relay/index.js +486 -0
  5. package/dist/app-store-relay/react.cjs +1 -0
  6. package/dist/app-store-relay/react.d.ts +15 -0
  7. package/dist/app-store-relay/react.js +65 -0
  8. package/dist/browser-storage-Cx9eW-bm.mjs +205 -0
  9. package/dist/browser-storage-jJaIht4K.js +1 -0
  10. package/dist/client-ASLtHFLh.js +1 -0
  11. package/dist/client-CGdh8yoJ.mjs +234 -0
  12. package/dist/components/device-install/index.d.ts +1 -2
  13. package/dist/core/device-install/apple/provisioning.d.ts +58 -7
  14. package/dist/core/device-install/operations/limbuild-client.d.ts +15 -1
  15. package/dist/core/device-install/storage/browser-storage.d.ts +9 -5
  16. package/dist/core/device-install/types.d.ts +4 -1
  17. package/dist/device-build/index.cjs +1 -0
  18. package/dist/device-build/index.d.ts +4 -0
  19. package/dist/device-build/index.js +84 -0
  20. package/dist/device-build/react.cjs +1 -0
  21. package/dist/device-build/react.d.ts +20 -0
  22. package/dist/device-build/react.js +68 -0
  23. package/dist/device-build/signing.d.ts +20 -0
  24. package/dist/device-install/demo/demo.d.ts +0 -0
  25. package/dist/device-install/index.cjs +1 -1
  26. package/dist/device-install/index.d.ts +18 -3
  27. package/dist/device-install/index.js +583 -76
  28. package/dist/device-install/react.cjs +1 -1
  29. package/dist/device-install/react.d.ts +23 -1
  30. package/dist/device-install/react.js +98 -2
  31. package/dist/hooks/index.d.ts +1 -1
  32. package/dist/index-CMeQfhYy.js +22 -0
  33. package/dist/index-DFdCvi2_.mjs +11543 -0
  34. package/dist/index.cjs +1 -1
  35. package/dist/index.d.ts +0 -2
  36. package/dist/index.js +502 -495
  37. package/dist/limbuild-client-CgEncrgx.js +1 -0
  38. package/dist/limbuild-client-D7U7w342.mjs +81 -0
  39. package/dist/provisioning-DKbkBO-p.mjs +239 -0
  40. package/dist/provisioning-Va0PH4Kk.js +1 -0
  41. package/package.json +21 -1
  42. package/src/app-store-relay/index.test.ts +70 -0
  43. package/src/app-store-relay/index.ts +514 -0
  44. package/src/app-store-relay/react.ts +129 -0
  45. package/src/components/device-install/index.ts +1 -2
  46. package/src/core/device-install/apple/client.ts +29 -22
  47. package/src/core/device-install/apple/crypto.ts +9 -6
  48. package/src/core/device-install/apple/gsa-srp.ts +3 -7
  49. package/src/core/device-install/apple/provisioning.test.ts +84 -0
  50. package/src/core/device-install/apple/provisioning.ts +98 -16
  51. package/src/core/device-install/apple/relay.ts +5 -1
  52. package/src/core/device-install/operations/limbuild-client.ts +41 -4
  53. package/src/core/device-install/operations/operations.ts +3 -1
  54. package/src/core/device-install/operations/relay-client.ts +57 -27
  55. package/src/core/device-install/operations/usbmux.ts +3 -3
  56. package/src/core/device-install/operations/webusb.ts +9 -4
  57. package/src/core/device-install/storage/browser-storage.ts +43 -14
  58. package/src/core/device-install/types.ts +6 -8
  59. package/src/device-build/index.ts +42 -0
  60. package/src/device-build/react.ts +131 -0
  61. package/src/device-build/signing.ts +94 -0
  62. package/src/device-install/README.md +423 -0
  63. package/src/device-install/demo/demo.css +493 -0
  64. package/src/device-install/demo/demo.tsx +1069 -0
  65. package/src/device-install/demo/index.html +12 -0
  66. package/src/device-install/index.ts +49 -3
  67. package/src/device-install/react.ts +189 -1
  68. package/src/hooks/index.ts +1 -1
  69. package/src/index.ts +0 -3
  70. package/vite.config.ts +4 -0
  71. package/dist/components/device-install/device-install-dialog.d.ts +0 -5
  72. package/dist/device-install-dialog-CqxDEH85.mjs +0 -443
  73. package/dist/device-install-dialog-jvqQ-fuo.js +0 -2
  74. package/dist/device-install-dialog.css +0 -1
  75. package/dist/hooks/use-device-install.d.ts +0 -73
  76. package/dist/use-device-install-CAPli9MR.js +0 -31
  77. package/dist/use-device-install-H8dqqvbR.mjs +0 -13624
  78. package/src/components/device-install/device-install-dialog.css +0 -325
  79. package/src/components/device-install/device-install-dialog.tsx +0 -495
  80. package/src/hooks/use-device-install.ts +0 -1219
package/README.md CHANGED
@@ -4,14 +4,31 @@
4
4
 
5
5
  See [examples](../../examples/) to see how it can be used.
6
6
 
7
- ## Real Device Installation
8
-
9
- `@limrun/ui` also includes a browser-based iPhone installation flow:
10
-
11
- - `@limrun/ui/device-install/react` exports the headless `useDeviceInstall` hook for clients that want to render their own UI.
12
- - `@limrun/ui/device-install` exports the guided `DeviceInstallDialog` UI, which walks users through a signed device build, USB access, browser pairing, and installation.
13
-
14
- WebUSB requires a Chromium browser and a secure context. Pair records and signing assets, including the `.p12` password, are stored in the browser's IndexedDB.
7
+ ## Real Device Installation Primitives
8
+
9
+ `@limrun/ui` includes browser primitives for building your own iPhone
10
+ installation UI. The package no longer exports a guided install dialog.
11
+
12
+ - `@limrun/ui/app-store-relay` exports framework-agnostic Apple ID relay and Apple Developer Portal calls for teams, certificates, profiles, bundle IDs, and devices.
13
+ - `@limrun/ui/app-store-relay/react` exports thin React state helpers for Apple ID login.
14
+ - `@limrun/ui/device-build` exports signing asset helpers, signed build triggering, build log watching, and OTA install metadata.
15
+ - `@limrun/ui/device-build/react` exports build state helpers.
16
+ - `@limrun/ui/device-install` exports WebUSB access, pairing, pair-record storage, and install relay primitives.
17
+ - `@limrun/ui/device-install/react` exports focused React state for device access, pairing, and relay installation.
18
+
19
+ The primitives are intentionally low-level. Your app decides whether to create
20
+ or reuse Apple certificates and provisioning profiles, how to present devices
21
+ and bundle IDs, and when to persist signing assets.
22
+
23
+ ```ts
24
+ import { listAppleTeams, createAppleProfile } from '@limrun/ui/app-store-relay';
25
+ import { startSignedDeviceBuild } from '@limrun/ui/device-build';
26
+ import { requestUSBAccess, pairDevice, startDeviceInstall } from '@limrun/ui/device-install';
27
+ ```
28
+
29
+ WebUSB requires a Chromium browser and a secure context. Pair records and signing
30
+ assets, including the `.p12` password when provided, are stored in the browser's
31
+ IndexedDB only when you call the storage helpers.
15
32
 
16
33
  ### Releasing
17
34
 
@@ -0,0 +1,9 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("../client-ASLtHFLh.js"),u=require("../index-CMeQfhYy.js"),p=require("../provisioning-Va0PH4Kk.js"),P={name:"RSASSA-PKCS1-v1_5",modulusLength:2048,publicExponent:new Uint8Array([1,0,1]),hash:"SHA-256"};async function I(e){if(!crypto.subtle)throw new Error("WebCrypto is not available in this browser.");const t=await crypto.subtle.generateKey(P,!0,["sign","verify"]),r=new Uint8Array(await crypto.subtle.exportKey("spki",t.publicKey)),n=f(C(0),h(e),r,B(0,new Uint8Array)),i=new Uint8Array(await crypto.subtle.sign("RSASSA-PKCS1-v1_5",t.privateKey,N(n))),o=f(n,f(g("1.2.840.113549.1.1.11"),R()),E(i)),s=new Uint8Array(await crypto.subtle.exportKey("pkcs8",t.privateKey));return{privateKey:t.privateKey,privateKeyPKCS8Base64:y(s),publicKeySPKIBase64:y(r),csrPEM:U("CERTIFICATE REQUEST",o),csrBase64:y(o)}}function S(e){if(!e.certificateBase64&&!e.certificatePEM)throw new Error("certificateBase64 or certificatePEM is required.");const t=u.forge.pki.privateKeyFromPem(F("PRIVATE KEY",e.privateKeyPKCS8Base64)),r=e.certificatePEM?u.forge.pki.certificateFromPem(e.certificatePEM):u.forge.pki.certificateFromAsn1(u.forge.asn1.fromDer(u.forge.util.createBuffer(k(e.certificateBase64)))),n=u.forge.pkcs12.toPkcs12Asn1(t,[r],e.password,{algorithm:"3des",friendlyName:e.friendlyName}),i=u.forge.asn1.toDer(n).getBytes();return O(i)}function h(e){const t=[v("2.5.4.3",T(e.commonName))];return e.emailAddress&&t.push(v("1.2.840.113549.1.9.1",K(e.emailAddress))),f(...t)}function v(e,t){return q(f(g(e),t))}function f(...e){return d(48,A(...e))}function q(...e){return d(49,A(...e))}function B(e,t){return d(160+e,t)}function C(e){return d(2,new Uint8Array([e]))}function R(){return new Uint8Array([5,0])}function T(e){return d(12,new TextEncoder().encode(e))}function K(e){return d(22,new TextEncoder().encode(e))}function E(e){return d(3,A(new Uint8Array([0]),e))}function g(e){const t=e.split(".").map(n=>parseInt(n,10));if(t.length<2||t.some(n=>!Number.isFinite(n)))throw new Error(`Invalid OID: ${e}`);const r=[t[0]*40+t[1]];for(const n of t.slice(2)){const i=[n&127];let o=n>>7;for(;o>0;)i.unshift(o&127|128),o>>=7;r.push(...i)}return d(6,new Uint8Array(r))}function d(e,t){return A(new Uint8Array([e]),x(t.byteLength),t)}function x(e){if(e<128)return new Uint8Array([e]);const t=[];let r=e;for(;r>0;)t.unshift(r&255),r>>=8;return new Uint8Array([128|t.length,...t])}function A(...e){const t=e.reduce((i,o)=>i+o.byteLength,0),r=new Uint8Array(t);let n=0;for(const i of e)r.set(i,n),n+=i.byteLength;return r}function U(e,t){const n=y(t).match(/.{1,64}/g)??[];return`-----BEGIN ${e}-----
2
+ ${n.join(`
3
+ `)}
4
+ -----END ${e}-----
5
+ `}function F(e,t){const r=t.match(/.{1,64}/g)??[];return`-----BEGIN ${e}-----
6
+ ${r.join(`
7
+ `)}
8
+ -----END ${e}-----
9
+ `}function y(e){let t="";for(const r of e)t+=String.fromCharCode(r);return btoa(t)}function O(e){return btoa(e)}function k(e){return atob(e)}function N(e){const t=new Uint8Array(e.byteLength);return t.set(e),t.buffer}async function a({apiUrl:e,token:t,appleSessionId:r,request:n,label:i="Apple Developer Portal request",validatePortalResponse:o=!0,mapBody:s}){const c=await l.proxyProvisioningRequest(e,r,n,t);return o&&b(c.body,i),s?s(c.body,c):c}async function L(e){return a({...e,request:p.listTeamsRequest(),label:"Apple Developer team list",mapBody:t=>re([...t?.teams??[],...t?.availableProviders??[],...t?.provider?[t.provider]:[]])})}async function $({certificateKind:e="development",teamId:t="",...r}){return a({...r,request:e==="distribution"?p.findDistributionCertificatesRequest(t):p.findDevelopmentCertificatesRequest(t),label:"Apple Developer certificate list",mapBody:n=>n?.certRequests??[]})}async function G({certificateKind:e="development",teamId:t="",csrPEM:r,...n}){return a({...n,request:e==="distribution"?p.submitDistributionCSRRequest({csrPEM:r,teamID:t}):p.submitDevelopmentCSRRequest({csrPEM:r,teamID:t}),label:e==="distribution"?"Apple Distribution certificate creation":"Apple Development certificate creation",mapBody:i=>i?.certRequest})}async function H({certificateKind:e="development",certificateId:t,teamId:r="",...n}){return a({...n,request:e==="distribution"?p.downloadDistributionCertificateRequest(t,r):p.downloadCertificateRequest(t,r),label:"Apple certificate download",validatePortalResponse:!1,mapBody:(i,o)=>o})}async function M({certificateKind:e="development",certificateId:t,teamId:r="",...n}){return a({...n,request:{method:"POST",path:"/account/ios/certificate/revokeCertificate.action",payload:{teamId:r,certificateId:t,type:e==="distribution"?"WXV89964HE":"83Q87W3TGH"}},label:"Apple certificate deletion",mapBody:i=>i})}async function _({teamId:e="",search:t="",...r}){const n=t.trim().toLowerCase();return a({...r,request:p.findBundleIDRequest({bundleID:t,teamID:e}),label:"Apple bundle ID list",mapBody:i=>{const o=i?.appIds??[];return n?o.filter(s=>[s.identifier,s.bundleId,s.name].some(c=>typeof c=="string"&&c.toLowerCase().includes(n))):o}})}async function j({teamId:e="",bundleId:t,name:r,...n}){return a({...n,request:p.createBundleIDRequest({bundleID:t,teamID:e,name:r}),label:"Apple bundle ID creation",mapBody:i=>i?.appId})}async function V({teamId:e="",appIdId:t,bundleId:r,name:n,...i}){return a({...i,request:{method:"POST",path:"/account/ios/identifiers/updateAppId.action",payload:{teamId:e,appIdId:t,...r?{identifier:r}:{},...n?{name:n}:{}}},label:"Apple bundle ID update",mapBody:o=>o?.appId})}async function W({teamId:e="",appIdId:t,...r}){return a({...r,request:{method:"POST",path:"/account/ios/identifiers/deleteAppId.action",payload:{teamId:e,appIdId:t}},label:"Apple bundle ID deletion",mapBody:n=>n})}async function Q({teamId:e="",deviceUDID:t="",...r}){const n=D(t);return a({...r,request:p.findDeviceRequest({deviceUDID:t,teamID:e}),label:"Apple device list",mapBody:i=>{const o=i?.devices??[];return n?o.filter(s=>D(s.deviceNumber)===n):o}})}function D(e){return(e??"").replace(/-/g,"").replace(/[^a-fA-F0-9]/g,"").toUpperCase()}async function z({teamId:e="",deviceUDID:t,name:r,...n}){return a({...n,request:p.registerDeviceRequest({deviceUDID:t,teamID:e,name:r}),label:"Apple device registration",mapBody:i=>i?.device})}async function J({teamId:e="",deviceId:t,name:r,...n}){return a({...n,request:{method:"POST",path:"/account/ios/device/updateDevice.action",payload:{teamId:e,deviceId:t,...r?{name:r}:{}}},label:"Apple device update",mapBody:i=>i?.device})}async function X({teamId:e="",deviceId:t,...r}){return a({...r,request:{method:"POST",path:"/account/ios/device/deleteDevice.action",payload:{teamId:e,deviceId:t}},label:"Apple device deletion",mapBody:n=>n})}async function Y({profileKind:e="development",teamId:t="",bundleId:r="",...n}){return a({...n,request:e==="adhoc"?p.findAdHocProfilesRequest({bundleID:r,teamID:t}):p.findDevelopmentProfilesRequest({bundleID:r,teamID:t}),label:"Apple provisioning profile list",mapBody:i=>i?.provisioningProfiles??[]})}async function Z({profileKind:e="development",teamId:t="",bundleId:r,appIdId:n,certificateIds:i,deviceIds:o,name:s,...c}){const[m]=i;if(!m)throw new Error("At least one certificate ID is required to create an Apple provisioning profile.");return a({...c,request:e==="adhoc"?p.createAdHocProfileRequest({bundleID:r,teamID:t,appIDID:n,certificateID:m,deviceIDs:o,name:s}):p.createDevelopmentProfileRequest({bundleID:r,teamID:t,appIDID:n,certificateID:m,deviceIDs:o,name:s}),label:"Apple provisioning profile creation",mapBody:w=>w?.provisioningProfile})}async function ee({teamId:e="",profileId:t,...r}){return a({...r,request:p.downloadProfileRequest(t,e),label:"Apple provisioning profile download",validatePortalResponse:!1,mapBody:(n,i)=>i})}async function te({teamId:e="",profileId:t,...r}){return a({...r,request:{method:"POST",path:"/account/ios/profile/deleteProvisioningProfile.action",payload:{teamId:e,provisioningProfileId:t}},label:"Apple provisioning profile deletion",mapBody:n=>n})}function b(e,t){if(!e)throw new Error(`${t} returned an empty response.`);if(e.resultCode!==void 0&&e.resultCode!==0)throw new Error(`${t} failed: ${e.userString??e.resultString??e.resultCode}`)}function re(e){const t=new Set,r=[];for(const n of e){const i=String(n.teamId??n.providerId??n.publicProviderId??n.name??JSON.stringify(n));t.has(i)||(t.add(i),r.push(n))}return r}exports.createAppleRelaySession=l.createAppleRelaySession;exports.deleteAppleRelaySession=l.deleteAppleRelaySession;exports.fetchAppleAccountSession=l.fetchAppleAccountSession;exports.proxyPhoneTwoFactorCode=l.proxyPhoneTwoFactorCode;exports.proxySrpComplete=l.proxySrpComplete;exports.proxySrpInit=l.proxySrpInit;exports.proxyTwoFactorCode=l.proxyTwoFactorCode;exports.startBrowserOwnedAppleIDLogin=l.startBrowserOwnedAppleIDLogin;exports.triggerPhoneTwoFactor=l.triggerPhoneTwoFactor;exports.triggerTrustedDeviceTwoFactor=l.triggerTrustedDeviceTwoFactor;exports.AppleGsaSrpClient=u.AppleGsaSrpClient;exports.assertAppleDeveloperPortalResponseOK=b;exports.createAppleBundleID=j;exports.createAppleCertificate=G;exports.createAppleProfile=Z;exports.deleteAppleBundleID=W;exports.deleteAppleCertificate=M;exports.deleteAppleDevice=X;exports.deleteAppleProfile=te;exports.downloadAppleCertificate=H;exports.downloadAppleProfile=ee;exports.exportAppleCertificateP12=S;exports.generateAppleSigningKeyAndCSR=I;exports.listAppleBundleIDs=_;exports.listAppleCertificates=$;exports.listAppleDevices=Q;exports.listAppleProfiles=Y;exports.listAppleTeams=L;exports.registerAppleDevice=z;exports.requestAppleProvisioning=a;exports.updateAppleBundleID=V;exports.updateAppleDevice=J;
@@ -0,0 +1,102 @@
1
+ import { AppleDeveloperPortalAppID, AppleDeveloperPortalDevice, AppleDeveloperPortalResponse, AppleDeveloperPortalTeam, AppleProvisioningRequest, AppleRelayResponse } from '../core/device-install/apple';
2
+ export * from '../core/device-install/apple/client';
3
+ export * from '../core/device-install/apple/crypto';
4
+ export * from '../core/device-install/apple/gsa-srp';
5
+ export type { AppleDeveloperPortalAppID, AppleDeveloperPortalDevice, AppleDeveloperPortalResponse, AppleDeveloperPortalTeam, AppleProvisioningRequest, AppleRelayResponse, } from '../core/device-install/apple';
6
+ export { createAppleRelaySession, deleteAppleRelaySession, fetchAppleAccountSession, proxyPhoneTwoFactorCode, proxySrpComplete, proxySrpInit, proxyTwoFactorCode, triggerPhoneTwoFactor, triggerTrustedDeviceTwoFactor, } from '../core/device-install/apple';
7
+ export type AppleRelayClientOptions = {
8
+ apiUrl: string;
9
+ token?: string;
10
+ appleSessionId: string;
11
+ };
12
+ export type AppleTeamScopedOptions = AppleRelayClientOptions & {
13
+ teamId?: string;
14
+ };
15
+ export type AppleCertificateKind = 'development' | 'distribution';
16
+ export type AppleProfileKind = 'development' | 'adhoc';
17
+ export type RequestAppleProvisioningOptions<T = unknown> = AppleRelayClientOptions & {
18
+ request: AppleProvisioningRequest;
19
+ label?: string;
20
+ validatePortalResponse?: boolean;
21
+ mapBody?: (body: AppleDeveloperPortalResponse | undefined, response: AppleRelayResponse<T>) => T;
22
+ };
23
+ export type MappedAppleProvisioningOptions<T> = RequestAppleProvisioningOptions<T> & {
24
+ mapBody: (body: AppleDeveloperPortalResponse | undefined, response: AppleRelayResponse<T>) => T;
25
+ };
26
+ export type ListAppleCertificatesOptions = AppleTeamScopedOptions & {
27
+ certificateKind?: AppleCertificateKind;
28
+ };
29
+ export type CreateAppleCertificateOptions = AppleTeamScopedOptions & {
30
+ certificateKind?: AppleCertificateKind;
31
+ csrPEM: string;
32
+ };
33
+ export type DownloadAppleCertificateOptions = AppleTeamScopedOptions & {
34
+ certificateKind?: AppleCertificateKind;
35
+ certificateId: string;
36
+ };
37
+ export type DeleteAppleCertificateOptions = DownloadAppleCertificateOptions;
38
+ export type ListAppleBundleIDsOptions = AppleTeamScopedOptions & {
39
+ search?: string;
40
+ };
41
+ export type CreateAppleBundleIDOptions = AppleTeamScopedOptions & {
42
+ bundleId: string;
43
+ name?: string;
44
+ };
45
+ export type UpdateAppleBundleIDOptions = AppleTeamScopedOptions & {
46
+ appIdId: string;
47
+ bundleId?: string;
48
+ name?: string;
49
+ };
50
+ export type DeleteAppleBundleIDOptions = AppleTeamScopedOptions & {
51
+ appIdId: string;
52
+ };
53
+ export type ListAppleDevicesOptions = AppleTeamScopedOptions & {
54
+ deviceUDID?: string;
55
+ };
56
+ export type RegisterAppleDeviceOptions = AppleTeamScopedOptions & {
57
+ deviceUDID: string;
58
+ name?: string;
59
+ };
60
+ export type UpdateAppleDeviceOptions = AppleTeamScopedOptions & {
61
+ deviceId: string;
62
+ name?: string;
63
+ };
64
+ export type DeleteAppleDeviceOptions = AppleTeamScopedOptions & {
65
+ deviceId: string;
66
+ };
67
+ export type ListAppleProfilesOptions = AppleTeamScopedOptions & {
68
+ profileKind?: AppleProfileKind;
69
+ bundleId?: string;
70
+ };
71
+ export type CreateAppleProfileOptions = AppleTeamScopedOptions & {
72
+ profileKind?: AppleProfileKind;
73
+ bundleId: string;
74
+ appIdId: string;
75
+ certificateIds: string[];
76
+ deviceIds: string[];
77
+ name?: string;
78
+ };
79
+ export type DownloadAppleProfileOptions = AppleTeamScopedOptions & {
80
+ profileId: string;
81
+ };
82
+ export type DeleteAppleProfileOptions = DownloadAppleProfileOptions;
83
+ export declare function requestAppleProvisioning<T>(options: MappedAppleProvisioningOptions<T>): Promise<T>;
84
+ export declare function requestAppleProvisioning<T = AppleDeveloperPortalResponse>(options: RequestAppleProvisioningOptions<T>): Promise<AppleRelayResponse<T>>;
85
+ export declare function listAppleTeams(options: AppleRelayClientOptions): Promise<AppleDeveloperPortalTeam[]>;
86
+ export declare function listAppleCertificates({ certificateKind, teamId, ...options }: ListAppleCertificatesOptions): Promise<Record<string, unknown>[]>;
87
+ export declare function createAppleCertificate({ certificateKind, teamId, csrPEM, ...options }: CreateAppleCertificateOptions): Promise<Record<string, unknown> | undefined>;
88
+ export declare function downloadAppleCertificate({ certificateKind, certificateId, teamId, ...options }: DownloadAppleCertificateOptions): Promise<AppleRelayResponse>;
89
+ export declare function deleteAppleCertificate({ certificateKind, certificateId, teamId, ...options }: DeleteAppleCertificateOptions): Promise<AppleDeveloperPortalResponse | undefined>;
90
+ export declare function listAppleBundleIDs({ teamId, search, ...options }: ListAppleBundleIDsOptions): Promise<AppleDeveloperPortalAppID[]>;
91
+ export declare function createAppleBundleID({ teamId, bundleId, name, ...options }: CreateAppleBundleIDOptions): Promise<Record<string, unknown> | undefined>;
92
+ export declare function updateAppleBundleID({ teamId, appIdId, bundleId, name, ...options }: UpdateAppleBundleIDOptions): Promise<Record<string, unknown> | undefined>;
93
+ export declare function deleteAppleBundleID({ teamId, appIdId, ...options }: DeleteAppleBundleIDOptions): Promise<AppleDeveloperPortalResponse | undefined>;
94
+ export declare function listAppleDevices({ teamId, deviceUDID, ...options }: ListAppleDevicesOptions): Promise<AppleDeveloperPortalDevice[]>;
95
+ export declare function registerAppleDevice({ teamId, deviceUDID, name, ...options }: RegisterAppleDeviceOptions): Promise<Record<string, unknown> | undefined>;
96
+ export declare function updateAppleDevice({ teamId, deviceId, name, ...options }: UpdateAppleDeviceOptions): Promise<Record<string, unknown> | undefined>;
97
+ export declare function deleteAppleDevice({ teamId, deviceId, ...options }: DeleteAppleDeviceOptions): Promise<AppleDeveloperPortalResponse | undefined>;
98
+ export declare function listAppleProfiles({ profileKind, teamId, bundleId, ...options }: ListAppleProfilesOptions): Promise<Record<string, unknown>[]>;
99
+ export declare function createAppleProfile({ profileKind, teamId, bundleId, appIdId, certificateIds, deviceIds, name, ...options }: CreateAppleProfileOptions): Promise<Record<string, unknown> | undefined>;
100
+ export declare function downloadAppleProfile({ teamId, profileId, ...options }: DownloadAppleProfileOptions): Promise<AppleRelayResponse>;
101
+ export declare function deleteAppleProfile({ teamId, profileId, ...options }: DeleteAppleProfileOptions): Promise<AppleDeveloperPortalResponse | undefined>;
102
+ export declare function assertAppleDeveloperPortalResponseOK(response: AppleDeveloperPortalResponse | undefined, label: string): void;
@@ -0,0 +1,486 @@
1
+ import { p as D } from "../client-CGdh8yoJ.mjs";
2
+ import { c as he, d as Pe, f as qe, a as Be, b as Se, e as Ce, g as Re, s as Te, t as Ee, h as Ke } from "../client-CGdh8yoJ.mjs";
3
+ import { f as l } from "../index-DFdCvi2_.mjs";
4
+ import { A as xe } from "../index-DFdCvi2_.mjs";
5
+ import { l as w, f as g, a as I, s as h, b as P, d as q, c as B, e as S, g as C, h as R, r as T, i as E, j as K, k as U, m as x, n as k } from "../provisioning-DKbkBO-p.mjs";
6
+ const F = {
7
+ name: "RSASSA-PKCS1-v1_5",
8
+ modulusLength: 2048,
9
+ publicExponent: new Uint8Array([1, 0, 1]),
10
+ hash: "SHA-256"
11
+ };
12
+ async function re(e) {
13
+ if (!crypto.subtle)
14
+ throw new Error("WebCrypto is not available in this browser.");
15
+ const t = await crypto.subtle.generateKey(F, !0, ["sign", "verify"]), r = new Uint8Array(await crypto.subtle.exportKey("spki", t.publicKey)), n = u(
16
+ $(0),
17
+ N(e),
18
+ r,
19
+ L(0, new Uint8Array())
20
+ ), i = new Uint8Array(
21
+ await crypto.subtle.sign(
22
+ "RSASSA-PKCS1-v1_5",
23
+ t.privateKey,
24
+ J(n)
25
+ )
26
+ ), o = u(
27
+ n,
28
+ u(v("1.2.840.113549.1.1.11"), H()),
29
+ _(i)
30
+ ), s = new Uint8Array(await crypto.subtle.exportKey("pkcs8", t.privateKey));
31
+ return {
32
+ privateKey: t.privateKey,
33
+ privateKeyPKCS8Base64: d(s),
34
+ publicKeySPKIBase64: d(r),
35
+ csrPEM: V("CERTIFICATE REQUEST", o),
36
+ csrBase64: d(o)
37
+ };
38
+ }
39
+ function ne(e) {
40
+ if (!e.certificateBase64 && !e.certificatePEM)
41
+ throw new Error("certificateBase64 or certificatePEM is required.");
42
+ const t = l.pki.privateKeyFromPem(W("PRIVATE KEY", e.privateKeyPKCS8Base64)), r = e.certificatePEM ? l.pki.certificateFromPem(e.certificatePEM) : l.pki.certificateFromAsn1(
43
+ l.asn1.fromDer(l.util.createBuffer(z(e.certificateBase64)))
44
+ ), n = l.pkcs12.toPkcs12Asn1(t, [r], e.password, {
45
+ algorithm: "3des",
46
+ friendlyName: e.friendlyName
47
+ }), i = l.asn1.toDer(n).getBytes();
48
+ return Q(i);
49
+ }
50
+ function N(e) {
51
+ const t = [m("2.5.4.3", G(e.commonName))];
52
+ return e.emailAddress && t.push(m("1.2.840.113549.1.9.1", M(e.emailAddress))), u(...t);
53
+ }
54
+ function m(e, t) {
55
+ return O(u(v(e), t));
56
+ }
57
+ function u(...e) {
58
+ return p(48, f(...e));
59
+ }
60
+ function O(...e) {
61
+ return p(49, f(...e));
62
+ }
63
+ function L(e, t) {
64
+ return p(160 + e, t);
65
+ }
66
+ function $(e) {
67
+ return p(2, new Uint8Array([e]));
68
+ }
69
+ function H() {
70
+ return new Uint8Array([5, 0]);
71
+ }
72
+ function G(e) {
73
+ return p(12, new TextEncoder().encode(e));
74
+ }
75
+ function M(e) {
76
+ return p(22, new TextEncoder().encode(e));
77
+ }
78
+ function _(e) {
79
+ return p(3, f(new Uint8Array([0]), e));
80
+ }
81
+ function v(e) {
82
+ const t = e.split(".").map((n) => parseInt(n, 10));
83
+ if (t.length < 2 || t.some((n) => !Number.isFinite(n)))
84
+ throw new Error(`Invalid OID: ${e}`);
85
+ const r = [t[0] * 40 + t[1]];
86
+ for (const n of t.slice(2)) {
87
+ const i = [n & 127];
88
+ let o = n >> 7;
89
+ for (; o > 0; )
90
+ i.unshift(o & 127 | 128), o >>= 7;
91
+ r.push(...i);
92
+ }
93
+ return p(6, new Uint8Array(r));
94
+ }
95
+ function p(e, t) {
96
+ return f(new Uint8Array([e]), j(t.byteLength), t);
97
+ }
98
+ function j(e) {
99
+ if (e < 128)
100
+ return new Uint8Array([e]);
101
+ const t = [];
102
+ let r = e;
103
+ for (; r > 0; )
104
+ t.unshift(r & 255), r >>= 8;
105
+ return new Uint8Array([128 | t.length, ...t]);
106
+ }
107
+ function f(...e) {
108
+ const t = e.reduce((i, o) => i + o.byteLength, 0), r = new Uint8Array(t);
109
+ let n = 0;
110
+ for (const i of e)
111
+ r.set(i, n), n += i.byteLength;
112
+ return r;
113
+ }
114
+ function V(e, t) {
115
+ const n = d(t).match(/.{1,64}/g) ?? [];
116
+ return `-----BEGIN ${e}-----
117
+ ${n.join(`
118
+ `)}
119
+ -----END ${e}-----
120
+ `;
121
+ }
122
+ function W(e, t) {
123
+ const r = t.match(/.{1,64}/g) ?? [];
124
+ return `-----BEGIN ${e}-----
125
+ ${r.join(`
126
+ `)}
127
+ -----END ${e}-----
128
+ `;
129
+ }
130
+ function d(e) {
131
+ let t = "";
132
+ for (const r of e)
133
+ t += String.fromCharCode(r);
134
+ return btoa(t);
135
+ }
136
+ function Q(e) {
137
+ return btoa(e);
138
+ }
139
+ function z(e) {
140
+ return atob(e);
141
+ }
142
+ function J(e) {
143
+ const t = new Uint8Array(e.byteLength);
144
+ return t.set(e), t.buffer;
145
+ }
146
+ async function a({
147
+ apiUrl: e,
148
+ token: t,
149
+ appleSessionId: r,
150
+ request: n,
151
+ label: i = "Apple Developer Portal request",
152
+ validatePortalResponse: o = !0,
153
+ mapBody: s
154
+ }) {
155
+ const c = await D(e, r, n, t);
156
+ return o && X(c.body, i), s ? s(c.body, c) : c;
157
+ }
158
+ async function ie(e) {
159
+ return a({
160
+ ...e,
161
+ request: w(),
162
+ label: "Apple Developer team list",
163
+ mapBody: (t) => Y([
164
+ ...t?.teams ?? [],
165
+ ...t?.availableProviders ?? [],
166
+ ...t?.provider ? [t.provider] : []
167
+ ])
168
+ });
169
+ }
170
+ async function oe({
171
+ certificateKind: e = "development",
172
+ teamId: t = "",
173
+ ...r
174
+ }) {
175
+ return a({
176
+ ...r,
177
+ request: e === "distribution" ? g(t) : I(t),
178
+ label: "Apple Developer certificate list",
179
+ mapBody: (n) => n?.certRequests ?? []
180
+ });
181
+ }
182
+ async function ae({
183
+ certificateKind: e = "development",
184
+ teamId: t = "",
185
+ csrPEM: r,
186
+ ...n
187
+ }) {
188
+ return a({
189
+ ...n,
190
+ request: e === "distribution" ? h({ csrPEM: r, teamID: t }) : P({ csrPEM: r, teamID: t }),
191
+ label: e === "distribution" ? "Apple Distribution certificate creation" : "Apple Development certificate creation",
192
+ mapBody: (i) => i?.certRequest
193
+ });
194
+ }
195
+ async function se({
196
+ certificateKind: e = "development",
197
+ certificateId: t,
198
+ teamId: r = "",
199
+ ...n
200
+ }) {
201
+ return a({
202
+ ...n,
203
+ request: e === "distribution" ? q(t, r) : B(t, r),
204
+ label: "Apple certificate download",
205
+ validatePortalResponse: !1,
206
+ mapBody: (i, o) => o
207
+ });
208
+ }
209
+ async function ce({
210
+ certificateKind: e = "development",
211
+ certificateId: t,
212
+ teamId: r = "",
213
+ ...n
214
+ }) {
215
+ return a({
216
+ ...n,
217
+ request: {
218
+ method: "POST",
219
+ path: "/account/ios/certificate/revokeCertificate.action",
220
+ payload: {
221
+ teamId: r,
222
+ certificateId: t,
223
+ type: e === "distribution" ? "WXV89964HE" : "83Q87W3TGH"
224
+ }
225
+ },
226
+ label: "Apple certificate deletion",
227
+ mapBody: (i) => i
228
+ });
229
+ }
230
+ async function pe({
231
+ teamId: e = "",
232
+ search: t = "",
233
+ ...r
234
+ }) {
235
+ const n = t.trim().toLowerCase();
236
+ return a({
237
+ ...r,
238
+ request: S({ bundleID: t, teamID: e }),
239
+ label: "Apple bundle ID list",
240
+ // Apple's listAppIds.action returns the full paginated list and does not
241
+ // honor a server-side search filter, so apply the `search` filter here.
242
+ mapBody: (i) => {
243
+ const o = i?.appIds ?? [];
244
+ return n ? o.filter(
245
+ (s) => [s.identifier, s.bundleId, s.name].some(
246
+ (c) => typeof c == "string" && c.toLowerCase().includes(n)
247
+ )
248
+ ) : o;
249
+ }
250
+ });
251
+ }
252
+ async function le({
253
+ teamId: e = "",
254
+ bundleId: t,
255
+ name: r,
256
+ ...n
257
+ }) {
258
+ return a({
259
+ ...n,
260
+ request: C({ bundleID: t, teamID: e, name: r }),
261
+ label: "Apple bundle ID creation",
262
+ mapBody: (i) => i?.appId
263
+ });
264
+ }
265
+ async function ue({
266
+ teamId: e = "",
267
+ appIdId: t,
268
+ bundleId: r,
269
+ name: n,
270
+ ...i
271
+ }) {
272
+ return a({
273
+ ...i,
274
+ request: {
275
+ method: "POST",
276
+ path: "/account/ios/identifiers/updateAppId.action",
277
+ payload: {
278
+ teamId: e,
279
+ appIdId: t,
280
+ ...r ? { identifier: r } : {},
281
+ ...n ? { name: n } : {}
282
+ }
283
+ },
284
+ label: "Apple bundle ID update",
285
+ mapBody: (o) => o?.appId
286
+ });
287
+ }
288
+ async function de({ teamId: e = "", appIdId: t, ...r }) {
289
+ return a({
290
+ ...r,
291
+ request: {
292
+ method: "POST",
293
+ path: "/account/ios/identifiers/deleteAppId.action",
294
+ payload: { teamId: e, appIdId: t }
295
+ },
296
+ label: "Apple bundle ID deletion",
297
+ mapBody: (n) => n
298
+ });
299
+ }
300
+ async function fe({
301
+ teamId: e = "",
302
+ deviceUDID: t = "",
303
+ ...r
304
+ }) {
305
+ const n = A(t);
306
+ return a({
307
+ ...r,
308
+ request: R({ deviceUDID: t, teamID: e }),
309
+ label: "Apple device list",
310
+ // Apple's listDevices.action returns the full paginated list and does not
311
+ // honor a server-side UDID filter, so apply the `deviceUDID` filter here.
312
+ mapBody: (i) => {
313
+ const o = i?.devices ?? [];
314
+ return n ? o.filter((s) => A(s.deviceNumber) === n) : o;
315
+ }
316
+ });
317
+ }
318
+ function A(e) {
319
+ return (e ?? "").replace(/-/g, "").replace(/[^a-fA-F0-9]/g, "").toUpperCase();
320
+ }
321
+ async function ye({
322
+ teamId: e = "",
323
+ deviceUDID: t,
324
+ name: r,
325
+ ...n
326
+ }) {
327
+ return a({
328
+ ...n,
329
+ request: T({ deviceUDID: t, teamID: e, name: r }),
330
+ label: "Apple device registration",
331
+ mapBody: (i) => i?.device
332
+ });
333
+ }
334
+ async function me({
335
+ teamId: e = "",
336
+ deviceId: t,
337
+ name: r,
338
+ ...n
339
+ }) {
340
+ return a({
341
+ ...n,
342
+ request: {
343
+ method: "POST",
344
+ path: "/account/ios/device/updateDevice.action",
345
+ payload: { teamId: e, deviceId: t, ...r ? { name: r } : {} }
346
+ },
347
+ label: "Apple device update",
348
+ mapBody: (i) => i?.device
349
+ });
350
+ }
351
+ async function Ae({ teamId: e = "", deviceId: t, ...r }) {
352
+ return a({
353
+ ...r,
354
+ request: {
355
+ method: "POST",
356
+ path: "/account/ios/device/deleteDevice.action",
357
+ payload: { teamId: e, deviceId: t }
358
+ },
359
+ label: "Apple device deletion",
360
+ mapBody: (n) => n
361
+ });
362
+ }
363
+ async function ve({
364
+ profileKind: e = "development",
365
+ teamId: t = "",
366
+ bundleId: r = "",
367
+ ...n
368
+ }) {
369
+ return a({
370
+ ...n,
371
+ request: e === "adhoc" ? E({ bundleID: r, teamID: t }) : K({ bundleID: r, teamID: t }),
372
+ label: "Apple provisioning profile list",
373
+ mapBody: (i) => i?.provisioningProfiles ?? []
374
+ });
375
+ }
376
+ async function be({
377
+ profileKind: e = "development",
378
+ teamId: t = "",
379
+ bundleId: r,
380
+ appIdId: n,
381
+ certificateIds: i,
382
+ deviceIds: o,
383
+ name: s,
384
+ ...c
385
+ }) {
386
+ const [y] = i;
387
+ if (!y)
388
+ throw new Error("At least one certificate ID is required to create an Apple provisioning profile.");
389
+ return a({
390
+ ...c,
391
+ request: e === "adhoc" ? U({
392
+ bundleID: r,
393
+ teamID: t,
394
+ appIDID: n,
395
+ certificateID: y,
396
+ deviceIDs: o,
397
+ name: s
398
+ }) : x({
399
+ bundleID: r,
400
+ teamID: t,
401
+ appIDID: n,
402
+ certificateID: y,
403
+ deviceIDs: o,
404
+ name: s
405
+ }),
406
+ label: "Apple provisioning profile creation",
407
+ mapBody: (b) => b?.provisioningProfile
408
+ });
409
+ }
410
+ async function De({
411
+ teamId: e = "",
412
+ profileId: t,
413
+ ...r
414
+ }) {
415
+ return a({
416
+ ...r,
417
+ request: k(t, e),
418
+ label: "Apple provisioning profile download",
419
+ validatePortalResponse: !1,
420
+ mapBody: (n, i) => i
421
+ });
422
+ }
423
+ async function we({ teamId: e = "", profileId: t, ...r }) {
424
+ return a({
425
+ ...r,
426
+ request: {
427
+ method: "POST",
428
+ path: "/account/ios/profile/deleteProvisioningProfile.action",
429
+ payload: { teamId: e, provisioningProfileId: t }
430
+ },
431
+ label: "Apple provisioning profile deletion",
432
+ mapBody: (n) => n
433
+ });
434
+ }
435
+ function X(e, t) {
436
+ if (!e)
437
+ throw new Error(`${t} returned an empty response.`);
438
+ if (e.resultCode !== void 0 && e.resultCode !== 0)
439
+ throw new Error(
440
+ `${t} failed: ${e.userString ?? e.resultString ?? e.resultCode}`
441
+ );
442
+ }
443
+ function Y(e) {
444
+ const t = /* @__PURE__ */ new Set(), r = [];
445
+ for (const n of e) {
446
+ const i = String(
447
+ n.teamId ?? n.providerId ?? n.publicProviderId ?? n.name ?? JSON.stringify(n)
448
+ );
449
+ t.has(i) || (t.add(i), r.push(n));
450
+ }
451
+ return r;
452
+ }
453
+ export {
454
+ xe as AppleGsaSrpClient,
455
+ X as assertAppleDeveloperPortalResponseOK,
456
+ le as createAppleBundleID,
457
+ ae as createAppleCertificate,
458
+ be as createAppleProfile,
459
+ he as createAppleRelaySession,
460
+ de as deleteAppleBundleID,
461
+ ce as deleteAppleCertificate,
462
+ Ae as deleteAppleDevice,
463
+ we as deleteAppleProfile,
464
+ Pe as deleteAppleRelaySession,
465
+ se as downloadAppleCertificate,
466
+ De as downloadAppleProfile,
467
+ ne as exportAppleCertificateP12,
468
+ qe as fetchAppleAccountSession,
469
+ re as generateAppleSigningKeyAndCSR,
470
+ pe as listAppleBundleIDs,
471
+ oe as listAppleCertificates,
472
+ fe as listAppleDevices,
473
+ ve as listAppleProfiles,
474
+ ie as listAppleTeams,
475
+ Be as proxyPhoneTwoFactorCode,
476
+ Se as proxySrpComplete,
477
+ Ce as proxySrpInit,
478
+ Re as proxyTwoFactorCode,
479
+ ye as registerAppleDevice,
480
+ a as requestAppleProvisioning,
481
+ Te as startBrowserOwnedAppleIDLogin,
482
+ Ee as triggerPhoneTwoFactor,
483
+ Ke as triggerTrustedDeviceTwoFactor,
484
+ ue as updateAppleBundleID,
485
+ me as updateAppleDevice
486
+ };
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const t=require("react"),R=require("../client-ASLtHFLh.js");require("../index-CMeQfhYy.js");function m({limbuildApiUrl:n,token:u}){const[g,o]=t.useState("idle"),[f,i]=t.useState(),[w,l]=t.useState(),[h,d]=t.useState(),[v,c]=t.useState(),r=t.useRef(void 0),S=t.useCallback(async()=>{await r.current?.close().catch(()=>{}),r.current=void 0,i(void 0),l(void 0),d(void 0),c(void 0),o("idle")},[]);t.useEffect(()=>()=>{r.current?.close(),r.current=void 0},[]);const b=t.useCallback(async({accountName:s,password:a})=>{o("authenticating"),c(void 0),await r.current?.close().catch(()=>{});try{const e=await R.startBrowserOwnedAppleIDLogin({limbuildApiUrl:n,token:u,accountName:s,password:a});return r.current=e,i(e),l(e.completeResponse),d(e.twoFactorChallengeResponse),o(e.requiresTwoFactor?"two-factor-required":"authenticated"),e}catch(e){i(void 0),r.current=void 0,c(p(e)),o("error");return}},[n,u]),C=t.useCallback(async s=>{const a=r.current;if(!a)throw new Error("Start Apple ID login before submitting a two-factor code.");o("authenticating"),c(void 0);try{const e=await a.finishTwoFactor(s);return o("authenticated"),e}catch(e){c(p(e)),o("error");return}},[]),y=t.useCallback(async()=>{const s=r.current;if(!s)throw new Error("Start Apple ID login before finalizing the Apple session.");return s.finalize()},[]);return{status:g,session:f,completeResponse:w,twoFactorChallengeResponse:h,error:v,startLogin:b,submitTwoFactorCode:C,finalize:y,close:S}}function p(n){return n instanceof Error?n.message:String(n)}exports.useAppleIDLogin=m;
@@ -0,0 +1,15 @@
1
+ import { AppleIDLoginInput, AppleIDLoginResult, AppleRelayResponse } from './index';
2
+ export type UseAppleIDLoginOptions = Pick<AppleIDLoginInput, 'limbuildApiUrl' | 'token'>;
3
+ export type AppleIDLoginStatus = 'idle' | 'authenticating' | 'two-factor-required' | 'authenticated' | 'error';
4
+ export type UseAppleIDLoginResult = {
5
+ status: AppleIDLoginStatus;
6
+ session?: AppleIDLoginResult;
7
+ completeResponse?: AppleRelayResponse;
8
+ twoFactorChallengeResponse?: AppleRelayResponse;
9
+ error?: string;
10
+ startLogin: (input: Pick<AppleIDLoginInput, 'accountName' | 'password'>) => Promise<AppleIDLoginResult | undefined>;
11
+ submitTwoFactorCode: (code: string) => Promise<AppleRelayResponse | undefined>;
12
+ finalize: () => Promise<AppleRelayResponse | undefined>;
13
+ close: () => Promise<void>;
14
+ };
15
+ export declare function useAppleIDLogin({ limbuildApiUrl, token }: UseAppleIDLoginOptions): UseAppleIDLoginResult;