Skip to content

Instantly share code, notes, and snippets.

@maxnowack
Created September 27, 2022 14:32
Show Gist options
  • Save maxnowack/754ee97d54b7ba9bf4db38335e18657c to your computer and use it in GitHub Desktop.
Save maxnowack/754ee97d54b7ba9bf4db38335e18657c to your computer and use it in GitHub Desktop.
import fetch from 'node-fetch'
interface ShortGUID {
value: string;
shouldFetchRootRecord: boolean;
}
interface ZoneID {
zoneName: string;
ownerRecordName: string;
zoneType: string;
}
interface CloudkitType {
value: string;
type: string;
}
interface CloudkitTitle {
value: string;
type: string;
}
interface Fields {
'cloudkit.type': CloudkitType;
'cloudkit.title': CloudkitTitle;
}
interface PluginFields {
[key: string]: any,
}
interface Created {
timestamp: number;
userRecordName: string;
deviceID: string;
}
interface Modified {
timestamp: number;
userRecordName: string;
deviceID: string;
}
interface ZoneID2 {
zoneName: string;
ownerRecordName: string;
zoneType: string;
}
interface Share2 {
recordName: string;
zoneID: ZoneID2;
}
interface NameComponents {
givenName: string;
familyName: string;
}
interface LookupInfo {
emailAddress: string;
}
interface UserIdentity {
userRecordName: string;
nameComponents: NameComponents;
lookupInfo: LookupInfo;
}
interface Participant {
participantId: string;
userIdentity: UserIdentity;
type: string;
acceptanceStatus: string;
permission: string;
orgUser: boolean;
}
interface NameComponents2 {
givenName: string;
familyName: string;
}
interface LookupInfo2 {
emailAddress: string;
}
interface UserIdentity2 {
userRecordName: string;
nameComponents: NameComponents2;
lookupInfo: LookupInfo2;
}
interface Owner {
participantId: string;
userIdentity: UserIdentity2;
type: string;
acceptanceStatus: string;
permission: string;
orgUser: boolean;
}
interface Share {
recordName: string;
recordType: string;
fields: Fields;
pluginFields: PluginFields;
recordChangeTag: string;
created: Created;
modified: Modified;
share: Share2;
publicPermission: string;
participants: Participant[];
owner: Owner;
displayedHostname: string;
shortGUID: string;
}
interface LastEditorName {
value: string;
type: string;
}
interface Extension {
value: string;
type: string;
}
interface Basehash {
value: string;
type: string;
}
interface Size {
value: number;
type: string;
}
interface EncryptedBasename {
value: string;
type: string;
}
interface Quarantine {
value: string;
type: string;
}
interface Mtime {
value: number;
type: string;
}
interface Value {
fileChecksum: string;
size: number;
wrappingKey: string;
referenceChecksum: string;
downloadURL: string;
}
interface FileContent {
value: Value;
type: string;
}
interface PublicSharingPermission {
value: number;
type: string;
}
interface Fields2 {
lastEditorName: LastEditorName;
extension: Extension;
basehash: Basehash;
size: Size;
encryptedBasename: EncryptedBasename;
quarantine: Quarantine;
mtime: Mtime;
fileContent: FileContent;
publicSharingPermission: PublicSharingPermission;
}
interface PluginFields2 {
}
interface Created2 {
timestamp: number;
userRecordName: string;
deviceID: string;
}
interface Modified2 {
timestamp: number;
userRecordName: string;
deviceID: string;
}
interface ZoneID3 {
zoneName: string;
ownerRecordName: string;
zoneType: string;
}
interface Share3 {
recordName: string;
zoneID: ZoneID3;
}
interface RootRecord {
recordName: string;
recordType: string;
fields: Fields2;
pluginFields: PluginFields2;
recordChangeTag: string;
created: Created2;
modified: Modified2;
deleted: boolean;
share: Share3;
displayedHostname: string;
shortGUID: string;
}
interface NameComponents3 {
givenName: string;
familyName: string;
}
interface LookupInfo3 {
emailAddress: string;
}
interface OwnerIdentity {
userRecordName: string;
nameComponents: NameComponents3;
lookupInfo: LookupInfo3;
}
export interface iCloudInfo {
shortGUID: ShortGUID;
containerIdentifier: string;
environment: string;
databaseScope: string;
zoneID: ZoneID;
share: Share;
rootRecordName: string;
rootRecord: RootRecord;
ancestorRecords: any[];
ownerIdentity: OwnerIdentity;
potentialMatchList: any[];
}
const getGuidFromUrl = (url: string) => {
const regex = /icloud\.com\/iclouddrive\/(.{25})/gi
const result = regex.exec(url)
if (!result || !result[1]) throw new Error(`Cannot get iCloud guid from url '${url}'`)
return result[1]
}
const iCloudDataUrl = 'https://ckdatabasews.icloud.com/database/1/com.apple.cloudkit/production/public/records/resolve'
const getiCloudInfo = async (url: string): Promise<iCloudInfo> => fetch(iCloudDataUrl, {
method: 'post',
body: JSON.stringify({
shortGUIDs: [{ value: getGuidFromUrl(url) }],
})
})
.then(r => r.json())
.then(r => (r.results && r.results[0]) || undefined)
export default getiCloudInfo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment