@owlmeans/server-job 0.1.18-rc.2 → 0.1.18-rc.21
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/README.md +36 -86
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/server-job/SKILL.md +60 -107
- package/build/actions/cancel.d.ts +3 -4
- package/build/actions/cancel.d.ts.map +1 -1
- package/build/actions/cancel.js +11 -6
- package/build/actions/cancel.js.map +1 -1
- package/build/actions/get.d.ts +3 -4
- package/build/actions/get.d.ts.map +1 -1
- package/build/actions/get.js +6 -4
- package/build/actions/get.js.map +1 -1
- package/build/actions/list.d.ts +3 -4
- package/build/actions/list.d.ts.map +1 -1
- package/build/actions/list.js +10 -12
- package/build/actions/list.js.map +1 -1
- package/build/actions/watch.d.ts +5 -6
- package/build/actions/watch.d.ts.map +1 -1
- package/build/actions/watch.js +21 -20
- package/build/actions/watch.js.map +1 -1
- package/build/entrypoints.d.ts +3 -4
- package/build/entrypoints.d.ts.map +1 -1
- package/build/entrypoints.js +10 -10
- package/build/entrypoints.js.map +1 -1
- package/build/helper.d.ts +3 -5
- package/build/helper.d.ts.map +1 -1
- package/build/helper.js +9 -11
- package/build/helper.js.map +1 -1
- package/build/index.d.ts +0 -3
- package/build/index.d.ts.map +1 -1
- package/build/index.js +0 -3
- package/build/index.js.map +1 -1
- package/build/types.d.ts +18 -46
- package/build/types.d.ts.map +1 -1
- package/build/utils/index.d.ts +2 -2
- package/build/utils/index.d.ts.map +1 -1
- package/build/utils/index.js +2 -2
- package/build/utils/index.js.map +1 -1
- package/build/utils/policy.d.ts +7 -0
- package/build/utils/policy.d.ts.map +1 -0
- package/build/utils/policy.js +10 -0
- package/build/utils/policy.js.map +1 -0
- package/build/utils/view.d.ts +18 -0
- package/build/utils/view.d.ts.map +1 -0
- package/build/utils/view.js +94 -0
- package/build/utils/view.js.map +1 -0
- package/package.json +17 -14
- package/src/actions/cancel.ts +15 -12
- package/src/actions/get.ts +10 -10
- package/src/actions/list.ts +15 -21
- package/src/actions/watch.ts +24 -25
- package/src/helper.ts +10 -18
- package/src/index.ts +0 -3
- package/src/types.ts +21 -48
- package/src/utils/index.ts +2 -2
- package/src/utils/policy.ts +20 -0
- package/src/utils/view.ts +102 -0
- package/tests/view.spec.ts +55 -0
- package/src/consts.ts +0 -28
- package/src/entrypoints.ts +0 -56
- package/src/schemas.ts +0 -19
- package/src/utils/owner.ts +0 -60
- package/src/utils/resource.ts +0 -40
package/src/utils/owner.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import type { BasicConfig, BasicContext } from '@owlmeans/context'
|
|
2
|
-
import type { AbstractRequest } from '@owlmeans/entrypoint'
|
|
3
|
-
import { AuthorizationError } from '@owlmeans/auth'
|
|
4
|
-
import type { Criteria } from '@owlmeans/resource'
|
|
5
|
-
import type { JobRecord } from '@owlmeans/queue'
|
|
6
|
-
import { DEFAULT_OWNER_FIELD } from '../consts.js'
|
|
7
|
-
import type { JobHandlerOptions } from '../types.js'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* The subject a job is attributed to.
|
|
11
|
-
*
|
|
12
|
-
* Profile first, user second — the same pair `@owlmeans/server-socket` addresses a connection by,
|
|
13
|
-
* so a job enqueued for one profile of a multi-profile account is not visible to the others.
|
|
14
|
-
*/
|
|
15
|
-
export const jobOwnerOf = (req: AbstractRequest): string | undefined =>
|
|
16
|
-
req.auth?.profileId ?? req.auth?.userId
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @throws {AuthorizationError} when the request carries no authenticated subject.
|
|
20
|
-
*/
|
|
21
|
-
export const requireJobOwner = (req: AbstractRequest): string => {
|
|
22
|
-
const owner = jobOwnerOf(req)
|
|
23
|
-
if (owner == null || owner === '') {
|
|
24
|
-
throw new AuthorizationError()
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return owner
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export const ownerFieldOf = (opts?: JobHandlerOptions): string =>
|
|
31
|
-
opts?.ownerField ?? DEFAULT_OWNER_FIELD
|
|
32
|
-
|
|
33
|
-
/** What one record says its owner is — the payload's own field, never a broker one. */
|
|
34
|
-
export const ownerOf = (record: JobRecord, opts?: JobHandlerOptions): unknown =>
|
|
35
|
-
(record.data as Record<string, unknown> | undefined)?.[ownerFieldOf(opts)]
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* Who this request reads the queue as: the owner every record must name, or `undefined` for a
|
|
39
|
-
* request that reads it unscoped.
|
|
40
|
-
*
|
|
41
|
-
* `undefined` is reachable only through {@link JobHandlerOptions.admin}. Absent an admin check
|
|
42
|
-
* every read is narrowed to the caller's own jobs and an anonymous request is refused, so a group
|
|
43
|
-
* wired with no options at all is scoped rather than open.
|
|
44
|
-
*
|
|
45
|
-
* @throws {AuthorizationError}
|
|
46
|
-
*/
|
|
47
|
-
export const jobViewer = async <C extends BasicConfig, T extends BasicContext<C>>(
|
|
48
|
-
req: AbstractRequest, ctx: T, opts?: JobHandlerOptions
|
|
49
|
-
): Promise<string | undefined> => {
|
|
50
|
-
if (opts?.admin != null && await opts.admin(req, ctx as BasicContext<BasicConfig>)) {
|
|
51
|
-
return undefined
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
return requireJobOwner(req)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/** The criteria one viewer reads the queue through; nothing to add when they read it unscoped. */
|
|
58
|
-
export const jobScope = (
|
|
59
|
-
viewer: string | undefined, opts?: JobHandlerOptions
|
|
60
|
-
): Criteria<JobRecord> => viewer == null ? {} : { [`data.${ownerFieldOf(opts)}`]: viewer }
|
package/src/utils/resource.ts
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import type { BasicConfig, BasicContext } from '@owlmeans/context'
|
|
2
|
-
import type { JobRecord, QueueResource } from '@owlmeans/queue'
|
|
3
|
-
import { UnknownJob } from '@owlmeans/queue'
|
|
4
|
-
import type { Context, JobHandlerOptions } from '../types.js'
|
|
5
|
-
import { ownerOf } from './owner.js'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* The queue these handlers read.
|
|
9
|
-
*
|
|
10
|
-
* Named by the declaration or, with nothing named, the context's sole declared queue — which
|
|
11
|
-
* `ctx.jobs()` refuses to guess once a second queue exists, so an app that grows one is told to
|
|
12
|
-
* name it rather than quietly served the wrong backlog.
|
|
13
|
-
*/
|
|
14
|
-
export const jobsOf = <D = unknown, R = unknown>(
|
|
15
|
-
ctx: BasicContext<BasicConfig>, opts?: JobHandlerOptions
|
|
16
|
-
): QueueResource<D, R> => (ctx as unknown as Context).jobs<D, R>(opts?.queue)
|
|
17
|
-
|
|
18
|
-
/** Does this viewer own that record? An unscoped viewer (`undefined`) owns everything. */
|
|
19
|
-
export const owns = (
|
|
20
|
-
record: JobRecord, viewer: string | undefined, opts?: JobHandlerOptions
|
|
21
|
-
): boolean => viewer == null || ownerOf(record, opts) === viewer
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* One job, as this viewer is allowed to see it.
|
|
25
|
-
*
|
|
26
|
-
* A job that exists but belongs to someone else answers exactly as an absent one does: telling an
|
|
27
|
-
* unauthorized caller apart from a wrong id is what turns an id space into an enumeration oracle.
|
|
28
|
-
*
|
|
29
|
-
* @throws {UnknownJob}
|
|
30
|
-
*/
|
|
31
|
-
export const readOwnedJob = async <D = unknown, R = unknown>(
|
|
32
|
-
resource: QueueResource<D, R>, id: string, viewer: string | undefined, opts?: JobHandlerOptions
|
|
33
|
-
): Promise<JobRecord<D, R>> => {
|
|
34
|
-
const record = await resource.load(id)
|
|
35
|
-
if (record == null || !owns(record, viewer, opts)) {
|
|
36
|
-
throw new UnknownJob(`${resource.queue}:${id}`)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return record
|
|
40
|
-
}
|