@heyputer/puter.js 1.0.0
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.
- package/APACHE_LICENSE.txt +201 -0
- package/README.md +88 -0
- package/doc/devlog.md +49 -0
- package/package.json +31 -0
- package/src/bg.png +0 -0
- package/src/bg.webp +0 -0
- package/src/index.js +745 -0
- package/src/lib/APICallLogger.js +110 -0
- package/src/lib/EventListener.js +51 -0
- package/src/lib/RequestError.js +6 -0
- package/src/lib/filesystem/APIFS.js +73 -0
- package/src/lib/filesystem/CacheFS.js +243 -0
- package/src/lib/filesystem/PostMessageFS.js +40 -0
- package/src/lib/filesystem/definitions.js +39 -0
- package/src/lib/path.js +509 -0
- package/src/lib/polyfills/localStorage.js +92 -0
- package/src/lib/polyfills/xhrshim.js +233 -0
- package/src/lib/socket.io/socket.io.esm.min.js +7 -0
- package/src/lib/socket.io/socket.io.esm.min.js.map +1 -0
- package/src/lib/socket.io/socket.io.js +4385 -0
- package/src/lib/socket.io/socket.io.js.map +1 -0
- package/src/lib/socket.io/socket.io.min.js +7 -0
- package/src/lib/socket.io/socket.io.min.js.map +1 -0
- package/src/lib/socket.io/socket.io.msgpack.min.js +7 -0
- package/src/lib/socket.io/socket.io.msgpack.min.js.map +1 -0
- package/src/lib/utils.js +620 -0
- package/src/lib/xdrpc.js +104 -0
- package/src/modules/AI.js +680 -0
- package/src/modules/Apps.js +215 -0
- package/src/modules/Auth.js +171 -0
- package/src/modules/Debug.js +39 -0
- package/src/modules/Drivers.js +278 -0
- package/src/modules/FSItem.js +139 -0
- package/src/modules/FileSystem/index.js +187 -0
- package/src/modules/FileSystem/operations/copy.js +64 -0
- package/src/modules/FileSystem/operations/deleteFSEntry.js +59 -0
- package/src/modules/FileSystem/operations/getReadUrl.js +42 -0
- package/src/modules/FileSystem/operations/mkdir.js +62 -0
- package/src/modules/FileSystem/operations/move.js +75 -0
- package/src/modules/FileSystem/operations/read.js +46 -0
- package/src/modules/FileSystem/operations/readdir.js +102 -0
- package/src/modules/FileSystem/operations/rename.js +58 -0
- package/src/modules/FileSystem/operations/sign.js +103 -0
- package/src/modules/FileSystem/operations/space.js +40 -0
- package/src/modules/FileSystem/operations/stat.js +95 -0
- package/src/modules/FileSystem/operations/symlink.js +55 -0
- package/src/modules/FileSystem/operations/upload.js +440 -0
- package/src/modules/FileSystem/operations/write.js +65 -0
- package/src/modules/FileSystem/utils/getAbsolutePathForApp.js +21 -0
- package/src/modules/Hosting.js +138 -0
- package/src/modules/KV.js +301 -0
- package/src/modules/OS.js +95 -0
- package/src/modules/Perms.js +109 -0
- package/src/modules/PuterDialog.js +481 -0
- package/src/modules/Threads.js +75 -0
- package/src/modules/UI.js +1555 -0
- package/src/modules/Util.js +38 -0
- package/src/modules/Workers.js +120 -0
- package/src/modules/networking/PSocket.js +87 -0
- package/src/modules/networking/PTLS.js +100 -0
- package/src/modules/networking/PWispHandler.js +89 -0
- package/src/modules/networking/parsers.js +157 -0
- package/src/modules/networking/requests.js +282 -0
- package/src/services/APIAccess.js +46 -0
- package/src/services/FSRelay.js +20 -0
- package/src/services/Filesystem.js +122 -0
- package/src/services/NoPuterYet.js +20 -0
- package/src/services/XDIncoming.js +44 -0
- package/test/ai.test.js +214 -0
- package/test/fs.test.js +798 -0
- package/test/index.html +1183 -0
- package/test/kv.test.js +548 -0
- package/test/txt2speech.test.js +178 -0
- package/webpack.config.js +25 -0
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { TeePromise } from '@heyputer/putility/src/libs/promise.js';
|
|
2
|
+
import * as utils from '../lib/utils.js';
|
|
3
|
+
|
|
4
|
+
const gui_cache_keys = [
|
|
5
|
+
'has_set_default_app_user_permissions',
|
|
6
|
+
'window_sidebar_width',
|
|
7
|
+
'sidebar_items',
|
|
8
|
+
'menubar_style',
|
|
9
|
+
'user_preferences.auto_arrange_desktop',
|
|
10
|
+
'user_preferences.show_hidden_files',
|
|
11
|
+
'user_preferences.language',
|
|
12
|
+
'user_preferences.clock_visible',
|
|
13
|
+
'toolbar_auto_hide_enabled',
|
|
14
|
+
'has_seen_welcome_window',
|
|
15
|
+
'desktop_item_positions',
|
|
16
|
+
'desktop_icons_hidden',
|
|
17
|
+
'taskbar_position',
|
|
18
|
+
'has_seen_toolbar_animation',
|
|
19
|
+
];
|
|
20
|
+
class KV{
|
|
21
|
+
MAX_KEY_SIZE = 1024;
|
|
22
|
+
MAX_VALUE_SIZE = 400 * 1024;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Creates a new instance with the given authentication token, API origin, and app ID,
|
|
26
|
+
*
|
|
27
|
+
* @class
|
|
28
|
+
* @param {string} authToken - Token used to authenticate the user.
|
|
29
|
+
* @param {string} APIOrigin - Origin of the API server. Used to build the API endpoint URLs.
|
|
30
|
+
* @param {string} appID - ID of the app to use.
|
|
31
|
+
*/
|
|
32
|
+
constructor(context) {
|
|
33
|
+
this.authToken = context.authToken;
|
|
34
|
+
this.APIOrigin = context.APIOrigin;
|
|
35
|
+
this.appID = context.appID;
|
|
36
|
+
|
|
37
|
+
this.gui_cached = new TeePromise();
|
|
38
|
+
this.gui_cache_init = new TeePromise();
|
|
39
|
+
(async () => {
|
|
40
|
+
await this.gui_cache_init;
|
|
41
|
+
this.gui_cache_init = null;
|
|
42
|
+
const resp = await fetch(`${this.APIOrigin}/drivers/call`, {
|
|
43
|
+
method: 'POST',
|
|
44
|
+
headers: {
|
|
45
|
+
'Content-Type': 'text/plain;actually=json',
|
|
46
|
+
},
|
|
47
|
+
body: JSON.stringify({
|
|
48
|
+
interface: 'puter-kvstore',
|
|
49
|
+
method: 'get',
|
|
50
|
+
args: {
|
|
51
|
+
key: gui_cache_keys,
|
|
52
|
+
},
|
|
53
|
+
auth_token: this.authToken
|
|
54
|
+
}),
|
|
55
|
+
});
|
|
56
|
+
const arr_values = await resp.json();
|
|
57
|
+
if ( ! Array.isArray(arr_values?.result) ) {
|
|
58
|
+
this.gui_cached.resolve({});
|
|
59
|
+
setTimeout(() => {
|
|
60
|
+
this.gui_cached = null;
|
|
61
|
+
}, 4000);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const obj = {};
|
|
65
|
+
for ( let i = 0; i < gui_cache_keys.length; i++ ) {
|
|
66
|
+
obj[gui_cache_keys[i]] = arr_values.result[i];
|
|
67
|
+
}
|
|
68
|
+
this.gui_cached.resolve(obj);
|
|
69
|
+
setTimeout(() => {
|
|
70
|
+
this.gui_cached = null;
|
|
71
|
+
}, 4000);
|
|
72
|
+
})();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Sets a new authentication token.
|
|
77
|
+
*
|
|
78
|
+
* @param {string} authToken - The new authentication token.
|
|
79
|
+
* @memberof [KV]
|
|
80
|
+
* @returns {void}
|
|
81
|
+
*/
|
|
82
|
+
setAuthToken(authToken) {
|
|
83
|
+
this.authToken = authToken;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Sets the API origin.
|
|
88
|
+
*
|
|
89
|
+
* @param {string} APIOrigin - The new API origin.
|
|
90
|
+
* @memberof [KV]
|
|
91
|
+
* @returns {void}
|
|
92
|
+
*/
|
|
93
|
+
setAPIOrigin(APIOrigin) {
|
|
94
|
+
this.APIOrigin = APIOrigin;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Resolves to 'true' on success, or rejects with an error on failure
|
|
99
|
+
*
|
|
100
|
+
* `key` cannot be undefined or null.
|
|
101
|
+
* `key` size cannot be larger than 1mb.
|
|
102
|
+
* `value` size cannot be larger than 10mb.
|
|
103
|
+
* `expireAt` is a timestamp in sec since epoch. If provided, the key will expire at the given time.
|
|
104
|
+
*/
|
|
105
|
+
set = utils.make_driver_method(['key', 'value', 'expireAt'], 'puter-kvstore', undefined, 'set', {
|
|
106
|
+
preprocess: (args) => {
|
|
107
|
+
console.log(args);
|
|
108
|
+
|
|
109
|
+
// key cannot be undefined or null
|
|
110
|
+
if ( args.key === undefined || args.key === null ){
|
|
111
|
+
throw { message: 'Key cannot be undefined', code: 'key_undefined' };
|
|
112
|
+
}
|
|
113
|
+
// key size cannot be larger than MAX_KEY_SIZE
|
|
114
|
+
if ( args.key.length > this.MAX_KEY_SIZE ){
|
|
115
|
+
throw { message: 'Key size cannot be larger than ' + this.MAX_KEY_SIZE, code: 'key_too_large' };
|
|
116
|
+
}
|
|
117
|
+
// value size cannot be larger than MAX_VALUE_SIZE
|
|
118
|
+
if ( args.value && args.value.length > this.MAX_VALUE_SIZE ){
|
|
119
|
+
throw { message: 'Value size cannot be larger than ' + this.MAX_VALUE_SIZE, code: 'value_too_large' };
|
|
120
|
+
}
|
|
121
|
+
return args;
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Resolves to the value if the key exists, or `undefined` if the key does not exist. Rejects with an error on failure.
|
|
127
|
+
*/
|
|
128
|
+
async get(...args) {
|
|
129
|
+
// Condition for gui boot cache
|
|
130
|
+
if (
|
|
131
|
+
typeof args[0] === 'string' &&
|
|
132
|
+
gui_cache_keys.includes(args[0]) &&
|
|
133
|
+
this.gui_cached !== null
|
|
134
|
+
) {
|
|
135
|
+
this.gui_cache_init && this.gui_cache_init.resolve();
|
|
136
|
+
const cache = await this.gui_cached;
|
|
137
|
+
return cache[args[0]];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Normal get
|
|
141
|
+
return await this.get_(...args);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
get_ = utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'get', {
|
|
145
|
+
preprocess: (args) => {
|
|
146
|
+
// key size cannot be larger than MAX_KEY_SIZE
|
|
147
|
+
if ( args.key.length > this.MAX_KEY_SIZE ){
|
|
148
|
+
throw ({ message: 'Key size cannot be larger than ' + this.MAX_KEY_SIZE, code: 'key_too_large' });
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return args;
|
|
152
|
+
},
|
|
153
|
+
transform: (res) => {
|
|
154
|
+
return res;
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
incr = async (...args) => {
|
|
159
|
+
let options = {};
|
|
160
|
+
|
|
161
|
+
// arguments are required
|
|
162
|
+
if ( !args || args.length === 0 ){
|
|
163
|
+
throw ({ message: 'Arguments are required', code: 'arguments_required' });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
options.key = args[0];
|
|
167
|
+
options.amount = args[1] ?? 1;
|
|
168
|
+
|
|
169
|
+
// key size cannot be larger than MAX_KEY_SIZE
|
|
170
|
+
if ( options.key.length > this.MAX_KEY_SIZE ){
|
|
171
|
+
throw ({ message: 'Key size cannot be larger than ' + this.MAX_KEY_SIZE, code: 'key_too_large' });
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'incr').call(this, options);
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
decr = async (...args) => {
|
|
178
|
+
let options = {};
|
|
179
|
+
|
|
180
|
+
// arguments are required
|
|
181
|
+
if ( !args || args.length === 0 ){
|
|
182
|
+
throw ({ message: 'Arguments are required', code: 'arguments_required' });
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
options.key = args[0];
|
|
186
|
+
options.amount = args[1] ?? 1;
|
|
187
|
+
|
|
188
|
+
// key size cannot be larger than MAX_KEY_SIZE
|
|
189
|
+
if ( options.key.length > this.MAX_KEY_SIZE ){
|
|
190
|
+
throw ({ message: 'Key size cannot be larger than ' + this.MAX_KEY_SIZE, code: 'key_too_large' });
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'decr').call(this, options);
|
|
194
|
+
};
|
|
195
|
+
|
|
196
|
+
expire = async (...args) => {
|
|
197
|
+
let options = {};
|
|
198
|
+
options.key = args[0];
|
|
199
|
+
options.ttl = args[1];
|
|
200
|
+
|
|
201
|
+
// key size cannot be larger than MAX_KEY_SIZE
|
|
202
|
+
if ( options.key.length > this.MAX_KEY_SIZE ){
|
|
203
|
+
throw ({ message: 'Key size cannot be larger than ' + this.MAX_KEY_SIZE, code: 'key_too_large' });
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return utils.make_driver_method(['key', 'ttl'], 'puter-kvstore', undefined, 'expire').call(this, options);
|
|
207
|
+
};
|
|
208
|
+
|
|
209
|
+
expireAt = async (...args) => {
|
|
210
|
+
let options = {};
|
|
211
|
+
options.key = args[0];
|
|
212
|
+
options.timestamp = args[1];
|
|
213
|
+
|
|
214
|
+
// key size cannot be larger than MAX_KEY_SIZE
|
|
215
|
+
if ( options.key.length > this.MAX_KEY_SIZE ){
|
|
216
|
+
throw ({ message: 'Key size cannot be larger than ' + this.MAX_KEY_SIZE, code: 'key_too_large' });
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return utils.make_driver_method(['key', 'timestamp'], 'puter-kvstore', undefined, 'expireAt').call(this, options);
|
|
220
|
+
};
|
|
221
|
+
|
|
222
|
+
// resolves to 'true' on success, or rejects with an error on failure
|
|
223
|
+
// will still resolve to 'true' if the key does not exist
|
|
224
|
+
del = utils.make_driver_method(['key'], 'puter-kvstore', undefined, 'del', {
|
|
225
|
+
preprocess: (args) => {
|
|
226
|
+
// key size cannot be larger than this.MAX_KEY_SIZE
|
|
227
|
+
if ( args.key.length > this.MAX_KEY_SIZE ){
|
|
228
|
+
throw ({ message: 'Key size cannot be larger than ' + this.MAX_KEY_SIZE, code: 'key_too_large' });
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return args;
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
list = async (...args) => {
|
|
236
|
+
let options = {};
|
|
237
|
+
let pattern;
|
|
238
|
+
let returnValues = false;
|
|
239
|
+
|
|
240
|
+
// list(true) or list(pattern, true) will return the key-value pairs
|
|
241
|
+
if ( (args && args.length === 1 && args[0] === true) || (args && args.length === 2 && args[1] === true) ){
|
|
242
|
+
options = {};
|
|
243
|
+
returnValues = true;
|
|
244
|
+
}
|
|
245
|
+
// return only the keys, default behavior
|
|
246
|
+
else {
|
|
247
|
+
options = { as: 'keys' };
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// list(pattern)
|
|
251
|
+
// list(pattern, true)
|
|
252
|
+
if ( (args && args.length === 1 && typeof args[0] === 'string') || (args && args.length === 2 && typeof args[0] === 'string' && args[1] === true) ){
|
|
253
|
+
pattern = args[0];
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return utils.make_driver_method([], 'puter-kvstore', undefined, 'list', {
|
|
257
|
+
transform: (res) => {
|
|
258
|
+
// glob pattern was provided
|
|
259
|
+
if ( pattern ){
|
|
260
|
+
// consider both the key and the value
|
|
261
|
+
if ( !returnValues ) {
|
|
262
|
+
let keys = res.filter((key) => {
|
|
263
|
+
return globMatch(pattern, key);
|
|
264
|
+
});
|
|
265
|
+
return keys;
|
|
266
|
+
} else {
|
|
267
|
+
let keys = res.filter((key_value_pair) => {
|
|
268
|
+
return globMatch(pattern, key_value_pair.key);
|
|
269
|
+
});
|
|
270
|
+
return keys;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return res;
|
|
275
|
+
},
|
|
276
|
+
}).call(this, options);
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
// resolve to 'true' on success, or rejects with an error on failure
|
|
280
|
+
// will still resolve to 'true' if there are no keys
|
|
281
|
+
flush = utils.make_driver_method([], 'puter-kvstore', undefined, 'flush');
|
|
282
|
+
|
|
283
|
+
// clear is an alias for flush
|
|
284
|
+
clear = this.flush;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
function globMatch(pattern, str) {
|
|
288
|
+
const escapeRegExp = (string) => string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
289
|
+
|
|
290
|
+
let regexPattern = escapeRegExp(pattern)
|
|
291
|
+
.replace(/\\\*/g, '.*') // Replace * with .*
|
|
292
|
+
.replace(/\\\?/g, '.') // Replace ? with .
|
|
293
|
+
.replace(/\\\[/g, '[') // Replace [ with [
|
|
294
|
+
.replace(/\\\]/g, ']') // Replace ] with ]
|
|
295
|
+
.replace(/\\\^/g, '^'); // Replace ^ with ^
|
|
296
|
+
|
|
297
|
+
let re = new RegExp('^' + regexPattern + '$');
|
|
298
|
+
return re.test(str);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export default KV;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as utils from '../lib/utils.js'
|
|
2
|
+
|
|
3
|
+
class OS{
|
|
4
|
+
/**
|
|
5
|
+
* Creates a new instance with the given authentication token, API origin, and app ID,
|
|
6
|
+
*
|
|
7
|
+
* @class
|
|
8
|
+
* @param {string} authToken - Token used to authenticate the user.
|
|
9
|
+
* @param {string} APIOrigin - Origin of the API server. Used to build the API endpoint URLs.
|
|
10
|
+
* @param {string} appID - ID of the app to use.
|
|
11
|
+
*/
|
|
12
|
+
constructor (context) {
|
|
13
|
+
this.authToken = context.authToken;
|
|
14
|
+
this.APIOrigin = context.APIOrigin;
|
|
15
|
+
this.appID = context.appID;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Sets a new authentication token.
|
|
20
|
+
*
|
|
21
|
+
* @param {string} authToken - The new authentication token.
|
|
22
|
+
* @memberof [OS]
|
|
23
|
+
* @returns {void}
|
|
24
|
+
*/
|
|
25
|
+
setAuthToken (authToken) {
|
|
26
|
+
this.authToken = authToken;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Sets the API origin.
|
|
31
|
+
*
|
|
32
|
+
* @param {string} APIOrigin - The new API origin.
|
|
33
|
+
* @memberof [Apps]
|
|
34
|
+
* @returns {void}
|
|
35
|
+
*/
|
|
36
|
+
setAPIOrigin (APIOrigin) {
|
|
37
|
+
this.APIOrigin = APIOrigin;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
user = function(...args){
|
|
41
|
+
let options;
|
|
42
|
+
|
|
43
|
+
// If first argument is an object, it's the options
|
|
44
|
+
if (typeof args[0] === 'object' && args[0] !== null) {
|
|
45
|
+
options = args[0];
|
|
46
|
+
} else {
|
|
47
|
+
// Otherwise, we assume separate arguments are provided
|
|
48
|
+
options = {
|
|
49
|
+
success: args[0],
|
|
50
|
+
error: args[1],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
let query = '';
|
|
55
|
+
if(options?.query){
|
|
56
|
+
query = '?' + new URLSearchParams(options.query).toString();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return new Promise((resolve, reject) => {
|
|
60
|
+
const xhr = utils.initXhr('/whoami' + query, this.APIOrigin, this.authToken, 'get');
|
|
61
|
+
|
|
62
|
+
// set up event handlers for load and error events
|
|
63
|
+
utils.setupXhrEventHandlers(xhr, options.success, options.error, resolve, reject);
|
|
64
|
+
|
|
65
|
+
xhr.send();
|
|
66
|
+
})
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
version = function(...args){
|
|
70
|
+
let options;
|
|
71
|
+
|
|
72
|
+
// If first argument is an object, it's the options
|
|
73
|
+
if (typeof args[0] === 'object' && args[0] !== null) {
|
|
74
|
+
options = args[0];
|
|
75
|
+
} else {
|
|
76
|
+
// Otherwise, we assume separate arguments are provided
|
|
77
|
+
options = {
|
|
78
|
+
success: args[0],
|
|
79
|
+
error: args[1],
|
|
80
|
+
// Add more if needed...
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return new Promise((resolve, reject) => {
|
|
85
|
+
const xhr = utils.initXhr('/version', this.APIOrigin, this.authToken, 'get');
|
|
86
|
+
|
|
87
|
+
// set up event handlers for load and error events
|
|
88
|
+
utils.setupXhrEventHandlers(xhr, options.success, options.error, resolve, reject);
|
|
89
|
+
|
|
90
|
+
xhr.send();
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export default OS
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
export default class Perms {
|
|
2
|
+
constructor (context) {
|
|
3
|
+
this.authToken = context.authToken;
|
|
4
|
+
this.APIOrigin = context.APIOrigin;
|
|
5
|
+
}
|
|
6
|
+
setAuthToken (authToken) {
|
|
7
|
+
this.authToken = authToken;
|
|
8
|
+
}
|
|
9
|
+
setAPIOrigin (APIOrigin) {
|
|
10
|
+
this.APIOrigin = APIOrigin;
|
|
11
|
+
}
|
|
12
|
+
async req_ (route, body) {
|
|
13
|
+
const resp = await fetch(
|
|
14
|
+
this.APIOrigin + route, {
|
|
15
|
+
method: body ? 'POST' : 'GET',
|
|
16
|
+
headers: {
|
|
17
|
+
Authorization: `Bearer ${this.authToken}`,
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
},
|
|
20
|
+
...(body ? { body: JSON.stringify(body) } : {}),
|
|
21
|
+
}
|
|
22
|
+
);
|
|
23
|
+
return await resp.json();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Grant Permissions
|
|
27
|
+
async grantUser (target_username, permission) {
|
|
28
|
+
return await this.req_('/auth/grant-user-user', {
|
|
29
|
+
target_username, permission,
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async grantGroup (group_uid, permission) {
|
|
34
|
+
return await this.req_('/auth/grant-user-group', {
|
|
35
|
+
group_uid, permission,
|
|
36
|
+
})
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async grantApp (app_uid, permission) {
|
|
40
|
+
return await this.req_('/auth/grant-user-app', {
|
|
41
|
+
app_uid, permission,
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async grantAppAnyUser (app_uid, permission) {
|
|
46
|
+
return await this.req_('/auth/grant-dev-app', {
|
|
47
|
+
app_uid, permission,
|
|
48
|
+
})
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async grantOrigin (origin, permission) {
|
|
52
|
+
return await this.req_('/auth/grant-user-app', {
|
|
53
|
+
origin, permission,
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Revoke Permissions
|
|
58
|
+
async revokeUser (target_username, permission) {
|
|
59
|
+
return await this.req_('/auth/revoke-user-user', {
|
|
60
|
+
target_username, permission,
|
|
61
|
+
})
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async revokeGroup (group_uid, permission) {
|
|
65
|
+
return await this.req_('/auth/revoke-user-group', {
|
|
66
|
+
group_uid, permission,
|
|
67
|
+
})
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async revokeApp (app_uid, permission) {
|
|
71
|
+
return await this.req_('/auth/revoke-user-app', {
|
|
72
|
+
app_uid, permission,
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async revokeAppAnyUser (app_uid, permission) {
|
|
77
|
+
return await this.req_('/auth/revoke-dev-app', {
|
|
78
|
+
app_uid, permission,
|
|
79
|
+
})
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async revokeOrigin (origin, permission) {
|
|
83
|
+
return await this.req_('/auth/revoke-user-app', {
|
|
84
|
+
origin, permission,
|
|
85
|
+
})
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Group Management
|
|
89
|
+
async createGroup (metadata = {}, extra = {}) {
|
|
90
|
+
return await this.req_('/group/create', {
|
|
91
|
+
metadata, extra,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async addUsersToGroup (uid, usernames) {
|
|
95
|
+
return await this.req_('/group/add-users', {
|
|
96
|
+
uid,
|
|
97
|
+
users: usernames ?? [],
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async removeUsersFromGroup (uid, usernames) {
|
|
101
|
+
return await this.req_('/group/remove-users', {
|
|
102
|
+
uid,
|
|
103
|
+
users: usernames ?? [],
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
async listGroups () {
|
|
107
|
+
return await this.req_('/group/list');
|
|
108
|
+
}
|
|
109
|
+
}
|