@axium/storage 0.2.0 → 0.2.2
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/dist/server.d.ts +2 -5
- package/dist/server.js +16 -40
- package/package.json +2 -2
package/dist/server.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Schema } from '@axium/server/database';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Generated, Selectable } from 'kysely';
|
|
3
3
|
import type { StorageItemMetadata, StorageLimits, StorageUsage } from './common.js';
|
|
4
4
|
import './polyfills.js';
|
|
5
5
|
declare module '@axium/server/database' {
|
|
@@ -53,15 +53,12 @@ declare module '@axium/server/config' {
|
|
|
53
53
|
export interface StorageItem extends StorageItemMetadata {
|
|
54
54
|
data: Uint8Array<ArrayBufferLike>;
|
|
55
55
|
}
|
|
56
|
-
export declare function parseItem<T extends Record<string, unknown> = Record<string, unknown>>(item: Selectable<Schema['storage']>
|
|
57
|
-
hash: string;
|
|
58
|
-
}): StorageItemMetadata<T>;
|
|
56
|
+
export declare function parseItem<T extends Record<string, unknown> = Record<string, unknown>>(item: Selectable<Schema['storage']>): StorageItemMetadata<T>;
|
|
59
57
|
/**
|
|
60
58
|
* Returns the current usage of the storage for a user in bytes.
|
|
61
59
|
*/
|
|
62
60
|
export declare function currentUsage(userId: string): Promise<StorageUsage>;
|
|
63
61
|
export declare function get<T extends Record<string, unknown> = Record<string, unknown>>(itemId: string): Promise<StorageItemMetadata<T>>;
|
|
64
|
-
export declare function withEncodedHash(eb: ExpressionBuilder<Schema, 'storage'>): import("kysely").AliasedExpression<string, "hash">;
|
|
65
62
|
export type ExternalLimitHandler = (userId?: string) => StorageLimits | Promise<StorageLimits>;
|
|
66
63
|
/**
|
|
67
64
|
* Define the handler to get limits for a user externally.
|
package/dist/server.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Permission } from '@axium/core/access';
|
|
2
|
+
import { checkAuthForItem, checkAuthForUser, getSessionAndUser } from '@axium/server/auth';
|
|
2
3
|
import { addConfigDefaults, config } from '@axium/server/config';
|
|
3
4
|
import { connect, database, expectedTypes } from '@axium/server/database';
|
|
4
5
|
import { dirs } from '@axium/server/io';
|
|
5
|
-
import {
|
|
6
|
+
import { getToken, parseBody, withError } from '@axium/server/requests';
|
|
6
7
|
import { addRoute } from '@axium/server/routes';
|
|
7
8
|
import { error } from '@sveltejs/kit';
|
|
8
9
|
import { createHash } from 'node:crypto';
|
|
@@ -52,6 +53,7 @@ export function parseItem(item) {
|
|
|
52
53
|
...item,
|
|
53
54
|
metadata: item.metadata,
|
|
54
55
|
dataURL: `/raw/storage/${item.id}`,
|
|
56
|
+
hash: item.hash.toHex(),
|
|
55
57
|
};
|
|
56
58
|
}
|
|
57
59
|
/**
|
|
@@ -73,13 +75,10 @@ export async function get(itemId) {
|
|
|
73
75
|
.selectFrom('storage')
|
|
74
76
|
.where('id', '=', itemId)
|
|
75
77
|
.selectAll()
|
|
76
|
-
|
|
78
|
+
.$narrowType()
|
|
77
79
|
.executeTakeFirstOrThrow();
|
|
78
80
|
return parseItem(result);
|
|
79
81
|
}
|
|
80
|
-
export function withEncodedHash(eb) {
|
|
81
|
-
return eb.fn('encode', ['hash', eb.val('hex')]).as('hash');
|
|
82
|
-
}
|
|
83
82
|
let _getLimits = null;
|
|
84
83
|
/**
|
|
85
84
|
* Define the handler to get limits for a user externally.
|
|
@@ -102,21 +101,15 @@ addRoute({
|
|
|
102
101
|
if (!config.storage.enabled)
|
|
103
102
|
error(503, 'User storage is disabled');
|
|
104
103
|
const itemId = event.params.id;
|
|
105
|
-
const item = await
|
|
106
|
-
|
|
107
|
-
error(404, 'Item not found');
|
|
108
|
-
await checkAuth(event, item.userId);
|
|
109
|
-
return item;
|
|
104
|
+
const { item } = await checkAuthForItem(event, 'storage', itemId, Permission.Read);
|
|
105
|
+
return parseItem(item);
|
|
110
106
|
},
|
|
111
107
|
async PATCH(event) {
|
|
112
108
|
if (!config.storage.enabled)
|
|
113
109
|
error(503, 'User storage is disabled');
|
|
114
110
|
const itemId = event.params.id;
|
|
115
111
|
const body = await parseBody(event, StorageItemUpdate);
|
|
116
|
-
|
|
117
|
-
if (!item)
|
|
118
|
-
error(404, 'Item not found');
|
|
119
|
-
await checkAuth(event, item.userId);
|
|
112
|
+
await checkAuthForItem(event, 'storage', itemId, Permission.Manage);
|
|
120
113
|
const values = {};
|
|
121
114
|
if ('publicPermission' in body)
|
|
122
115
|
values.publicPermission = body.publicPermission;
|
|
@@ -133,7 +126,6 @@ addRoute({
|
|
|
133
126
|
.where('id', '=', itemId)
|
|
134
127
|
.set(values)
|
|
135
128
|
.returningAll()
|
|
136
|
-
.returning(withEncodedHash)
|
|
137
129
|
.executeTakeFirstOrThrow()
|
|
138
130
|
.catch(withError('Could not update item')));
|
|
139
131
|
},
|
|
@@ -141,10 +133,8 @@ addRoute({
|
|
|
141
133
|
if (!config.storage.enabled)
|
|
142
134
|
error(503, 'User storage is disabled');
|
|
143
135
|
const itemId = event.params.id;
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
error(404, 'Item not found');
|
|
147
|
-
await checkAuth(event, item.userId);
|
|
136
|
+
const auth = await checkAuthForItem(event, 'storage', itemId, Permission.Manage);
|
|
137
|
+
const item = parseItem(auth.item);
|
|
148
138
|
await database
|
|
149
139
|
.deleteFrom('storage')
|
|
150
140
|
.where('id', '=', itemId)
|
|
@@ -168,10 +158,7 @@ addRoute({
|
|
|
168
158
|
if (!config.storage.enabled)
|
|
169
159
|
error(503, 'User storage is disabled');
|
|
170
160
|
const itemId = event.params.id;
|
|
171
|
-
const item = await
|
|
172
|
-
if (!item)
|
|
173
|
-
error(404, 'Item not found');
|
|
174
|
-
await checkAuth(event, item.userId);
|
|
161
|
+
const { item } = await checkAuthForItem(event, 'storage', itemId, Permission.Read);
|
|
175
162
|
if (item.type != 'inode/directory')
|
|
176
163
|
error(409, 'Item is not a directory');
|
|
177
164
|
const items = await database
|
|
@@ -179,7 +166,6 @@ addRoute({
|
|
|
179
166
|
.where('parentId', '=', itemId)
|
|
180
167
|
.where('trashedAt', '!=', null)
|
|
181
168
|
.selectAll()
|
|
182
|
-
.select(withEncodedHash)
|
|
183
169
|
.execute();
|
|
184
170
|
return items.map(parseItem);
|
|
185
171
|
},
|
|
@@ -228,7 +214,6 @@ addRoute({
|
|
|
228
214
|
.insertInto('storage')
|
|
229
215
|
.values({ userId: userId, hash, name, size, type, immutable: useCAS, parentId })
|
|
230
216
|
.returningAll()
|
|
231
|
-
.returning(withEncodedHash)
|
|
232
217
|
.executeTakeFirstOrThrow()
|
|
233
218
|
.catch(withError('Could not create item'));
|
|
234
219
|
const path = join(config.storage.data, result.id);
|
|
@@ -257,10 +242,7 @@ addRoute({
|
|
|
257
242
|
if (!config.storage.enabled)
|
|
258
243
|
error(503, 'User storage is disabled');
|
|
259
244
|
const itemId = event.params.id;
|
|
260
|
-
const item = await
|
|
261
|
-
if (!item)
|
|
262
|
-
error(404, 'Item not found');
|
|
263
|
-
await checkAuth(event, item.userId);
|
|
245
|
+
const { item } = await checkAuthForItem(event, 'storage', itemId, Permission.Read);
|
|
264
246
|
if (item.trashedAt)
|
|
265
247
|
error(410, 'Trashed items can not be downloaded');
|
|
266
248
|
const content = new Uint8Array(readFileSync(join(config.storage.data, item.id)));
|
|
@@ -275,16 +257,11 @@ addRoute({
|
|
|
275
257
|
if (!config.storage.enabled)
|
|
276
258
|
error(503, 'User storage is disabled');
|
|
277
259
|
const itemId = event.params.id;
|
|
278
|
-
const item = await
|
|
279
|
-
if (!item)
|
|
280
|
-
error(404, 'Item not found');
|
|
281
|
-
const { accessor } = await checkAuth(event, item.userId);
|
|
260
|
+
const { item } = await checkAuthForItem(event, 'storage', itemId, Permission.Edit);
|
|
282
261
|
if (item.immutable)
|
|
283
262
|
error(403, 'Item is immutable');
|
|
284
263
|
if (item.trashedAt)
|
|
285
264
|
error(410, 'Trashed items can not be changed');
|
|
286
|
-
if (item.userId != accessor.id)
|
|
287
|
-
error(403, 'Item editing is restricted to the owner');
|
|
288
265
|
const type = event.request.headers.get('content-type') || 'application/octet-stream';
|
|
289
266
|
// @todo: add this to the audit log
|
|
290
267
|
if (type != item.type)
|
|
@@ -308,7 +285,6 @@ addRoute({
|
|
|
308
285
|
.where('id', '=', itemId)
|
|
309
286
|
.set({ size, modifiedAt: new Date(), hash })
|
|
310
287
|
.returningAll()
|
|
311
|
-
.returning(withEncodedHash)
|
|
312
288
|
.executeTakeFirstOrThrow()
|
|
313
289
|
.catch(withError('Could not update item'));
|
|
314
290
|
await writeFile(join(config.storage.data, result.id), content).catch(withError('Could not write'));
|
|
@@ -322,7 +298,7 @@ addRoute({
|
|
|
322
298
|
if (!config.storage.enabled)
|
|
323
299
|
error(503, 'User storage is disabled');
|
|
324
300
|
const userId = event.params.id;
|
|
325
|
-
await
|
|
301
|
+
await checkAuthForUser(event, userId);
|
|
326
302
|
const [usage, limits] = await Promise.all([currentUsage(userId), getLimits(userId)]).catch(withError('Could not fetch data'));
|
|
327
303
|
return { usage, limits };
|
|
328
304
|
},
|
|
@@ -330,9 +306,9 @@ addRoute({
|
|
|
330
306
|
if (!config.storage.enabled)
|
|
331
307
|
error(503, 'User storage is disabled');
|
|
332
308
|
const userId = event.params.id;
|
|
333
|
-
await
|
|
309
|
+
await checkAuthForUser(event, userId);
|
|
334
310
|
const [items, usage, limits] = await Promise.all([
|
|
335
|
-
database.selectFrom('storage').where('userId', '=', userId).selectAll().
|
|
311
|
+
database.selectFrom('storage').where('userId', '=', userId).selectAll().execute(),
|
|
336
312
|
currentUsage(userId),
|
|
337
313
|
getLimits(userId),
|
|
338
314
|
]).catch(withError('Could not fetch data'));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axium/storage",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"author": "James Prevett <axium@jamespre.dev> (https://jamespre.dev)",
|
|
5
5
|
"description": "User file storage for Axium",
|
|
6
6
|
"funding": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"peerDependencies": {
|
|
34
34
|
"@axium/client": ">=0.1.0",
|
|
35
35
|
"@axium/core": ">=0.5.0",
|
|
36
|
-
"@axium/server": ">=0.
|
|
36
|
+
"@axium/server": ">=0.18.0",
|
|
37
37
|
"@sveltejs/kit": "^2.23.0",
|
|
38
38
|
"utilium": "^2.3.8"
|
|
39
39
|
},
|