IceDrive Internal API
We need a cookie in order to use the API, login
receives e-mail and password and returns cookie, which we can use later in API:
ice_drive_email
- IceDrive account e-mail
ice_drive_password
- IceDrive account password
ice_drive_cookie
- received after login
var $API_URL = "/API/Internal/V1/";
IceRequest
function can be used to POST
and GET
some data, we can have similar function in GO
as well
// code from the web app
function IceRequest(method, type, data) {
data = data || {};
data.sess = 1;
if (method == "POST") {
var fd = new FormData();
fd.append("request", type);
for (var key in data) {
fd.append(key, data[key]);
}
return new Promise(function (resolve, reject) {
fetch($API_URL, { method: "post", credentials: "include", body: fd })
.then(function (response) {
return response.json();
})
.then(function (data) {
if (data.error) reject(data);
resolve(data);
})
.catch(function (error) {
reject({ error: !0, code: 0, message: "API Error" });
});
});
} else {
var queryString = Object.keys(data)
.map(function (key) {
return key + "=" + data[key];
})
.join("&");
var url = $API_URL + "?request=" + type + "&" + queryString;
return new Promise(function (resolve, reject) {
var headers = {
Accept: "application/json",
"Content-Type": "application/json",
Cache: "no-cache",
};
fetch(url, { method: "GET", credentials: "include", headers: headers })
.then(function (response) {
return response.json();
})
.then(function (data) {
if (data.error) {
reject(data);
} else {
resolve(data);
}
})
.catch(function (error) {
reject({ error: !0, code: 0, message: "API Error" });
});
});
}
}
Login:
We need to call login
in order to get cookie
which is used in future requests:
IceRequest("POST", "login", { email: data.email, password: data.password })
Code the app:
// code from the web app
IceRequest("POST", "login", { email: data.email, password: data.password })
.then(function (rs) {
if (redir) window.location.href = redir;
else window.location.href = "/dashboard/";
})
.catch(function (error) {
if (error.code == 1200 || error.code == 1112) {
// Seems like this is called when e-mail is not confirmed
frmApiButtonReset(data.btnText);
modalEmailConfirm(data.email, !1);
return;
}
if (error.code == 6000) {
// When 2FA is enabled
twoFactor(error.userId, error.method, redir);
return;
}
frmApiError(error.message);
frmApiButtonReset(data.btnText);
});
Response:
JSON
returned from login
request is following:
{"error":false,"message":"Login successful","token":"ice-UUID_REDACTED","auth_data":{"id":"REDACTED","email":"REDACTED@REDACTED","level_id":"11","apiKey":"API_KEY_REDACTED","fullName":"REDACTED REDACTED","level_type":"free","plan":"Free","avatar_url":"https:\/\/icedrive.net\/assets\/avatar\/default.png","auth_type":"session","token":null}}
JSON.token
is the value we are interested, if JSON.error
is false.
Now, we have ice_drive_cookie
to call rest of APIs.
Make sure that icedrive
cookie have value JSON.token
(ice_drive_cookie
)
Generic User Data:
URL: https://icedrive.net/API/Internal/V1/?request=user-data&sess=1
//from app
return IceRequest("GET", "user-data", {})
Returns:
{
"id": "REDACTED",
"email": "REDACTED@REDACTED.REDACTED",
"level_id": 11,
"apiKey": "REDACTED",
"fullName": "REDACTED REDACTED",
"level_type": "free",
"plan": "Free",
"avatar_url": "https://icedrive.net/assets/avatar/default.png",
"auth_type": "session",
"token": null,
"error": false
}
Storage stat:
https://icedrive.net/API/Internal/V1/?request=stats-storage&sess=1
return IceRequest("GET", "stats-storage", {})
Returns:
{
"error": false,
"used": 0,
"used_human": "0.00 KB",
"max": 10737418240,
"max_human": "10.00 GB",
"free": 10737418240,
"free_human": "10.00 GB",
"pcent": 0,
"pcent_raw": 0
}
Get root folder - GET
:
https://icedrive.net/API/Internal/V1/?request=collection&type=cloud&folderId=0&sess=1
0
is hardcoded ID number for the root folder.
Response:
{
"error": false,
"id": 0,
"results": 3,
"data": [
{
"id": 83476825,
"uid": "folder-83476825",
"filename": "abc",
"parentId": 0,
"moddate": 1638726469,
"isFolder": 1,
"filesize": 0,
"extension": null,
"fave": 0,
"isPublic": 0,
"color": 0,
"isOwner": 1,
"isShared": 0,
"fileType": "folder",
"crypto": 0,
"thumbnail": null
},
{
"id": 83476880,
"uid": "folder-83476880",
"filename": "bvbb",
"parentId": 0,
"moddate": 1638726485,
"isFolder": 1,
"filesize": 0,
"extension": null,
"fave": 0,
"isPublic": 0,
"color": 0,
"isOwner": 1,
"isShared": 0,
"fileType": "folder",
"crypto": 0,
"thumbnail": null
},
{
"id": 708556066,
"uid": "file-708556066",
"filename": "a.js",
"parentId": 0,
"moddate": 1638723865,
"isFolder": 0,
"filesize": 1287,
"extension": "js",
"fave": 0,
"isPublic": 0,
"color": null,
"isOwner": 1,
"isShared": 0,
"fileType": "code",
"crypto": 0,
"thumbnail": null
}
]
}
As you can see we getting IDs for folder and files in the directory
Simiarly we can can list any folder via uid
:
https://icedrive.net/API/Internal/V1/?request=collection&type=cloud&folderId=folder-83476825&sess=1
As you can see folderId
is one of the IDs from above. \
Response is same as before, but if there is no files or folders, we getting following:
{
"error": false,
"id": 83476825,
"results": 0,
"data": []
}
Folder metadata:
https://icedrive.net/API/Internal/V1/?request=folder-properties&id=folder-83476825&sess=1
Response:
{
"error": false,
"isFolder": 1,
"folderId": 83476825,
"filename": "abc",
"moddate": 1638726469,
"num_folders": 0,
"num_files": 0,
"total_size": 0,
"isOwner": 1,
"owner": {}
}
File metadata:
https://icedrive.net/API/Internal/V1/?request=file-properties&id=file-708556066&sess=1
Response:
{
"error": false,
"isFolder": 0,
"id": 708556066,
"filename": "a.js",
"moddate": 1638723865,
"total_size": 1287,
"isOwner": 1,
"owner": []
}
id
points to folder or file we want to get details about.
Create new folder:
// data.request = folder-create
// data.type = folder-create
// data.parentId: folder-83478059 (or 0 if root)
// data.filename: aaa
// data.sess: 1
IceRequest("POST", "folder-create", data)
Response:
{
"error": false,
"id": 83478262,
"folderId": 83478262,
"name": "bbb",
"filename": "bbb",
"mtime": 1638727085,
"message": "Folder created"
}
Delete folder and files:
IceRequest("POST", "trash-add", { items: items })
Form data:
request=trash-add
items=folder-xxxxxx,folder-yyyyyy
sess=1
trash-restore
with same item(s) restores deleted file
erase
with same data deletes items from trash bin
Moving data:
request=move
items=folder-xxxxxx
folderId=yyyyyy
sess=1
items
points to comma seperated, files and folders we want to move
folderId
ponts to folder where we moving files and folders
Rename folder:
request=folder_rename
filename=new_name
id=folder-xxxxxxxx
sess=1
Rename files:
request=file-rename
filename=bbb
id=file-xxxx
keep_ext=true // we may need false
sess=1
Download file:
https://icedrive.net/API/Internal/V1/?request=download-multi&items=file-xxxxx&sess=1
where file-xxxxx
is a file ID
Response:
{
"error": false,
"urls": [
{
"id": 00000000, // REDACTED
"filename": "abc.xx",
"filesize": 1282,
"folderId": 0,
"moddate": 000000000, // REDACTED
"path": "",
"url": "https://icecube-eu-402.icedrive.io/download?p=REDACTED"
}
]
}
Download a folder as a zip file:
https://icedrive.net/API/Internal/V1/?request=zip-folder&id=folder-xxxxx&sess=1
Similar response as file download
Upload a file
The first thing is to get a list of endpoints (upload_endpoints
), which we can use to upload the file:
https://icedrive.net/API/Internal/V1/?request=geo-filserver-list&sess=1
Response:
{
"error": false,
"upload_endpoints": [
"https://icecube-eu-284.icedrive.io/deposit?p=iLzpwLUhYoHU_k0YjGeNHz60Bl0TwiNqaHzWIiczi_.VRZBfJ9Yh7Y6kXyhNl6e6.CUEV0_OJKDI5f7DueLgx0ZVd4ynOOc6i9DIyYFS5mfjkVXR4zLFlPqhn.CoVR9sb4aMhvrdvvauOL7vnfe5hA--",
"https://icecube-eu-305.icedrive.io/deposit?p=iLzpwLUhYoHU_k0YjGeNHz60Bl0TwiNqaHzWIiczi_.VRZBfJ9Yh7Y6kXyhNl6e6.CUEV0_OJKDI5f7DueLgx0ZVd4ynOOc6i9DIyYFS5mfjkVXR4zLFlPqhn.CoVR9sb4aMhvrdvvauOL7vnfe5hA--",
"https://icecube-eu-302.icedrive.io/deposit?p=iLzpwLUhYoHU_k0YjGeNHz60Bl0TwiNqaHzWIiczi_.VRZBfJ9Yh7Y6kXyhNl6e6.CUEV0_OJKDI5f7DueLgx0ZVd4ynOOc6i9DIyYFS5mfjkVXR4zLFlPqhn.CoVR9sb4aMhvrdvvauOL7vnfe5hA--",
...
"https://icecube-eu-282.icedrive.io/deposit?p=iLzpwLUhYoHU_k0YjGeNHz60Bl0TwiNqaHzWIiczi_.VRZBfJ9Yh7Y6kXyhNl6e6.CUEV0_OJKDI5f7DueLgx0ZVd4ynOOc6i9DIyYFS5mfjkVXR4zLFlPqhn.CoVR9sb4aMhvrdvvauOL7vnfe5hA--"
]
}
It's a long list of endpoinds, we can choose one and use for subsequent uploads.
One of the URL will be our Request URL.
Now we can use the URL to upload our target file
Example from the web app:
function (e) {
if ("add" == e.data.type) {
(userId = e.data.userId), (apiKey = e.data.apiKey);
var r = e.data.folderId.toString().replace(/\formData/g, "");
e.data.uploadId;
UploadSetup({
file: e.data.file,
uploadId: e.data.uploadId,
queueId: e.data.queueId,
filename: e.data.file.name,
folderId: r,
server: e.data.server, // one of the endpoints
dir_path: e.data.dir_path,
retry: 0,
});
}
},
function UploadSetup(e) {
e.server;
var r = !!e.file.lastModified && e.file.lastModified / 1e3;
e.startTime = Math.floor(Date.now());
var formData = new FormData();
if (
(formData.append("folderId", e.folderId),
r && formData.append("moddate", r),
e.dir_path && formData.append("dir_path", e.dir_path),
e.file.size <= chunkSize)
)
formData.append("files[]", e.file),
UploadFile(formData, e, !1, 0)
.then(function (r) {
postMessage({
type: "complete",
overwrite: e.overwrite,
queueId: e.queueId,
uploadId: e.uploadId,
fileId: r.id,
folderId: e.folderId,
fileObj: r.fileObj,
});
})
...
function UploadFile(e, r, d, t) {
return (
(d = d || !1),
new Promise(function (a, o) {
var i = 0,
l = new XMLHttpRequest();
l.open("POST", r.server, !0),
d && l.setRequestHeader("Content-Range", d),
(l.upload.onprogress = function (e) {
progress(
r.startTime,
t + e.loaded,
r.file.size,
r.uploadId,
e.loaded - i
),
(i = e.loaded);
}),
(l.upload.onerror = function () {
o("Upload Error");
}),
(l.upload.ontimeout = function () {
o("timeout");
}),
(l.onerror = function () {
o("Upload Error");
}),
(l.onload = function (e) {}),
(l.ontimeout = function () {}),
(l.upload.onloadend = function (e) {}),
(l.onloadend = function () {
if (l.status > 0) {
try {
var e = JSON.parse(l.response);
} catch (e) {
o("Server errror");
}
e.error ? o(e.message) : a(e);
}
}),
l.send(e);
})
);
}
If there is something else we need, commend and I'll try to extract it