-
Notifications
You must be signed in to change notification settings - Fork 1
/
libVES.Auth.js
133 lines (127 loc) · 5.09 KB
/
libVES.Auth.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/***************************************************************************
* ___ ___
* / \ / \ VESvault
* \__ / \ __/ Encrypt Everything without fear of losing the Key
* \\ // https://vesvault.com https://ves.host
* \\ //
* ___ \\_//
* / \ / \ VESauth: HTTP X-VES Authentication client
* \__ / \ __/
* \\ //
* \\ //
* \\_//
* / \
* \___/
*
*
* (c) 2021 VESvault Corp
* Jim Zubov <[email protected]>
*
* GNU General Public License v3
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* @title libVES
* @dev Send X-VES-Authorization: header to the external HTTPS server as a
* @dev proof of ownership of a particulat vaultItem
* @version 0.1a
*
* @author Jim Zubov <[email protected]> (VESvault Corp)
*
***************************************************************************/
libVES.Auth = function(optns) {
for (var k in optns) this[k] = optns[k];
return this;
};
libVES.Auth.prototype.getToken = function() {
if (this.vaultItem) return Promise.all([this.vaultItem.getId(), this.vaultItem.getField('verifyToken')]).then(function(flds) {
return 'vaultItem.' + flds[0] + '.' + flds[1];
});
else if (this.vaultKey) return Promise.all([this.vaultKey.getId(), this.vaultItem.getSessionToken()]).then(function(flds) {
return 'vaultKey.' + flds[0] + '.' + flds[1];
});
else if ((VES = this.VES) && VES.token) return this.VES.getVaultKey().then(function(vkey) {
return vkey.getId().then(function(id) {
return 'vaultKey.' + id + '.' + VES.token;
});
});
return Promise.reject({code: 'VESauth', message: 'No object to generate a VESauth token for'});
};
libVES.Auth.prototype.getData = function(url, type) {
return this.getToken().then(function(tkn) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
if (type) xhr.responseType = type;
xhr.onreadystatechange = function() {
switch(xhr.readyState) {
case 4:
if (xhr.status == 200) resolve(xhr.response);
else reject({code: xhr.status, message: xhr.statusText});
}
};
xhr.setRequestHeader('X-VES-Authorization', tkn);
xhr.send();
});
});
};
libVES.Auth.prototype.getJSON = function(url) {
return this.getData(url, 'json').then(function(json) {
var a = document.createElement('a');
a.href = url;
if (!a.hash) return json;
var path = a.hash.split(/\//);
for (var i = 1; i < path.length; i++) if (path[i]) {
if (json instanceof Array) json = json[Number(path[i])];
else if (json instanceof Object) json = json[path[i]];
else return null;
}
return json;
});
};
libVES.Auth.prototype.auth = function(token) {
return this.verify(token, true);
};
libVES.Auth.prototype.verify = function(token, auth) {
var tk = token.match(/^(\w*)\.(\d*)\.(.*)$/);
if (!tk) return Promise.reject(new libVES.Error('VESauth', 'Invalid VESauth token'));
var ves = new libVES({domain: (this.domain || '*'), token: tk[3]});
if (tk[1] == 'vaultItem') {
if (auth) return Promise.reject(new libVES.Error('VESauth', 'Verify token cannot be used for authentication'));
return Promise.resolve(this.vaultItem ? this.vaultItem.getId() : tk[2]).then(function(id) {
var vi = new libVES.VaultItem({id: id}, ves);
return vi.getFile().then(function(file) {
return vi.getField('deleted').then(function(f) {
if (f) throw new libVES.Error('VESauth', 'Verify token expired');
return file.getCreator();
});
});
});
}
if (tk[1] != 'vaultKey') return Promise.reject(new libVES.Error('VESauth', 'Unknown token type'));
if (this.vaultItem) return this.vaultItem.getId().then(function(id) {
var vi = new libVES.VaultItem({id: id}, ves);
return vi.getVaultEntries().then(function(vents) {
if (!auth && vents && vents.length) return ves.me();
if (vents && tk[2]) for (var i = 0; i < vents.length; i++) if (vents[i].vaultKey && Number(vents[i].vaultKey.id) == Number(tk[2])) return ves.me();
throw new libVES.Error('VESauth', 'ACL not authorized');
});
});
if (!auth) return ves.me();
return Promise.resolve(this.vaultKey ? this.vaultKey.getId() : tk[2]).then(function(id) {
return (new libVES.VaultKey({id: id}, ves)).getExternals().then(function(ext) {
if (!ext || !ext[0]) throw new libVES.Error('VESauth', 'Bad vaultKey for VESauth');
return ext[0].getDomain().then(function(dom) {
return ext[0].getExternalId().then(function(extid) {
if (!extid || !extid.match(/^[^\!\@]+\@[^\!\@]+$/)) throw new libVES.Error('VESauth', 'Bad vaultKey for VESauth');
if (dom && dom.toLowerCase() == ves.domain.toLowerCase()) return ves.me();
throw new libVES.Error('VESuath', 'VES domain does not match');
});
});
});
});
};