@sasjs/api 0.10.0 → 0.11.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/build/browser.js +375 -103
- package/build/cjs/corpus/code.js +44 -7
- package/build/cjs/corpus/runner.js +4 -1
- package/build/cjs/corpus/session.js +73 -0
- package/build/cjs/host/dispatch.js +35 -0
- package/build/cjs/index.js +3 -1
- package/build/cjs/routes/generated.js +16 -0
- package/build/cjs/routes/overlay.js +7 -17
- package/build/cjs/session/memory-host.js +74 -0
- package/build/cjs/session/service.js +65 -0
- package/build/esm/corpus/code.d.ts.map +1 -1
- package/build/esm/corpus/code.js +44 -7
- package/build/esm/corpus/runner.d.ts.map +1 -1
- package/build/esm/corpus/runner.js +4 -1
- package/build/esm/corpus/session.d.ts +16 -0
- package/build/esm/corpus/session.d.ts.map +1 -0
- package/build/esm/corpus/session.js +70 -0
- package/build/esm/host/dispatch.d.ts +6 -0
- package/build/esm/host/dispatch.d.ts.map +1 -1
- package/build/esm/host/dispatch.js +35 -0
- package/build/esm/index.d.ts +1 -0
- package/build/esm/index.d.ts.map +1 -1
- package/build/esm/index.js +1 -0
- package/build/esm/routes/generated.d.ts.map +1 -1
- package/build/esm/routes/generated.js +16 -0
- package/build/esm/routes/overlay.d.ts.map +1 -1
- package/build/esm/routes/overlay.js +7 -17
- package/build/esm/session/memory-host.d.ts +19 -0
- package/build/esm/session/memory-host.d.ts.map +1 -0
- package/build/esm/session/memory-host.js +70 -0
- package/build/esm/session/service.d.ts +62 -0
- package/build/esm/session/service.d.ts.map +1 -0
- package/build/esm/session/service.js +61 -0
- package/package.json +1 -1
package/build/browser.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* @sasjs/api 0.
|
|
1
|
+
/* @sasjs/api 0.11.0 - the SASjs Server API, for a service worker. https://github.com/sasjs/api */
|
|
2
2
|
"use strict";
|
|
3
3
|
var SASjsApi = (() => {
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -41,6 +41,7 @@ var SASjsApi = (() => {
|
|
|
41
41
|
PROVIDER_MANAGED: () => PROVIDER_MANAGED,
|
|
42
42
|
RECORD_CORPUS: () => RECORD_CORPUS,
|
|
43
43
|
ROUTES: () => ROUTES,
|
|
44
|
+
SESSION_CORPUS: () => SESSION_CORPUS,
|
|
44
45
|
STATIC_AUTHORIZED_ROUTES: () => STATIC_AUTHORIZED_ROUTES,
|
|
45
46
|
TAG_CAPABILITIES: () => TAG_CAPABILITIES,
|
|
46
47
|
TOP_LEVEL_ROUTES: () => TOP_LEVEL_ROUTES,
|
|
@@ -892,6 +893,14 @@ var SASjsApi = (() => {
|
|
|
892
893
|
{
|
|
893
894
|
status: 200,
|
|
894
895
|
description: "Ok"
|
|
896
|
+
},
|
|
897
|
+
{
|
|
898
|
+
status: 400,
|
|
899
|
+
description: '"code" is required / "code" must be a string / "code" is not allowed to be empty'
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
status: 401,
|
|
903
|
+
description: "Unauthorized"
|
|
895
904
|
}
|
|
896
905
|
]
|
|
897
906
|
},
|
|
@@ -920,6 +929,14 @@ var SASjsApi = (() => {
|
|
|
920
929
|
{
|
|
921
930
|
status: 200,
|
|
922
931
|
description: "Ok"
|
|
932
|
+
},
|
|
933
|
+
{
|
|
934
|
+
status: 400,
|
|
935
|
+
description: '"code" is required / "code" must be a string / "code" is not allowed to be empty'
|
|
936
|
+
},
|
|
937
|
+
{
|
|
938
|
+
status: 401,
|
|
939
|
+
description: "Unauthorized"
|
|
923
940
|
}
|
|
924
941
|
]
|
|
925
942
|
},
|
|
@@ -2461,7 +2478,6 @@ var SASjsApi = (() => {
|
|
|
2461
2478
|
};
|
|
2462
2479
|
var DIRECTORY = "Synchronising with an external auth provider needs a directory port, which this package does not have: a host decides which directory it holds accounts in, and answers this itself.";
|
|
2463
2480
|
var RUNTIME = "Starting a program needs a runtime port, which this package does not have: a host decides which languages it holds, and answers this itself until then.";
|
|
2464
|
-
var SESSION_RECORD = "A triggered session's record, log, output and state belong to the runtime that ran the program, and this package has no runtime port.";
|
|
2465
2481
|
var HOST_CONFIG = "The body is the host's own configuration - ports, run times and providers - which a mock states for itself and this package cannot know.";
|
|
2466
2482
|
var HOST_OWNED = "The host owns this report: it describes the host's own process and files, which a browser build has no equivalent of.";
|
|
2467
2483
|
var WEB_BUNDLE = "The host serves its own web bundle; there is no API decision here for this package to answer.";
|
|
@@ -2639,22 +2655,13 @@ var SASjsApi = (() => {
|
|
|
2639
2655
|
implemented: true,
|
|
2640
2656
|
responses: { 200: user }
|
|
2641
2657
|
},
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
},
|
|
2646
|
-
"GET /SASjsApi/session/{sessionId}/log": {
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
},
|
|
2650
|
-
"GET /SASjsApi/session/{sessionId}/output": {
|
|
2651
|
-
implemented: false,
|
|
2652
|
-
reason: SESSION_RECORD
|
|
2653
|
-
},
|
|
2654
|
-
"GET /SASjsApi/session/{sessionId}/state": {
|
|
2655
|
-
implemented: false,
|
|
2656
|
-
reason: SESSION_RECORD
|
|
2657
|
-
},
|
|
2658
|
+
// The port takes the owner as a uid and falls back to a username, which is
|
|
2659
|
+
// what sasjs/server records today - a host hands its sessions through as they
|
|
2660
|
+
// are, and the comparison tries the identifier first.
|
|
2661
|
+
"GET /SASjsApi/session/{sessionId}": { implemented: true },
|
|
2662
|
+
"GET /SASjsApi/session/{sessionId}/log": { implemented: true },
|
|
2663
|
+
"GET /SASjsApi/session/{sessionId}/output": { implemented: true },
|
|
2664
|
+
"GET /SASjsApi/session/{sessionId}/state": { implemented: true },
|
|
2658
2665
|
// STP - a stored program, on the runtime port
|
|
2659
2666
|
"GET /SASjsApi/stp/execute": { implemented: false, reason: RUNTIME },
|
|
2660
2667
|
"POST /SASjsApi/stp/execute": { implemented: false, reason: RUNTIME },
|
|
@@ -2811,6 +2818,14 @@ var SASjsApi = (() => {
|
|
|
2811
2818
|
const query = request.query || {};
|
|
2812
2819
|
const body = request.body || {};
|
|
2813
2820
|
const params = request.params || {};
|
|
2821
|
+
const sessionRequired = () => {
|
|
2822
|
+
if (!services.session)
|
|
2823
|
+
throw new ApiError(
|
|
2824
|
+
501,
|
|
2825
|
+
`This host has no session service, so it cannot answer ${routeId}.`
|
|
2826
|
+
);
|
|
2827
|
+
return services.session;
|
|
2828
|
+
};
|
|
2814
2829
|
const required = () => {
|
|
2815
2830
|
if (!records)
|
|
2816
2831
|
throw new ApiError(
|
|
@@ -2910,6 +2925,43 @@ var SASjsApi = (() => {
|
|
|
2910
2925
|
}
|
|
2911
2926
|
case "GET /SASjsApi/drive/filetree":
|
|
2912
2927
|
return { status: 200, body: await drive.tree(query._folderPath) };
|
|
2928
|
+
// ------------------------------------------------------------- sessions
|
|
2929
|
+
case "GET /SASjsApi/session/{sessionId}": {
|
|
2930
|
+
return {
|
|
2931
|
+
status: 200,
|
|
2932
|
+
body: await sessionRequired().summary(
|
|
2933
|
+
await caller(),
|
|
2934
|
+
String(params.sessionId ?? "")
|
|
2935
|
+
)
|
|
2936
|
+
};
|
|
2937
|
+
}
|
|
2938
|
+
case "GET /SASjsApi/session/{sessionId}/log": {
|
|
2939
|
+
return {
|
|
2940
|
+
status: 200,
|
|
2941
|
+
contents: await sessionRequired().log(
|
|
2942
|
+
await caller(),
|
|
2943
|
+
String(params.sessionId ?? "")
|
|
2944
|
+
)
|
|
2945
|
+
};
|
|
2946
|
+
}
|
|
2947
|
+
case "GET /SASjsApi/session/{sessionId}/output": {
|
|
2948
|
+
return {
|
|
2949
|
+
status: 200,
|
|
2950
|
+
contents: await sessionRequired().output(
|
|
2951
|
+
await caller(),
|
|
2952
|
+
String(params.sessionId ?? "")
|
|
2953
|
+
)
|
|
2954
|
+
};
|
|
2955
|
+
}
|
|
2956
|
+
case "GET /SASjsApi/session/{sessionId}/state": {
|
|
2957
|
+
return {
|
|
2958
|
+
status: 200,
|
|
2959
|
+
body: await sessionRequired().state(
|
|
2960
|
+
await caller(),
|
|
2961
|
+
String(params.sessionId ?? "")
|
|
2962
|
+
)
|
|
2963
|
+
};
|
|
2964
|
+
}
|
|
2913
2965
|
// ------------------------------------------------------------- records
|
|
2914
2966
|
//
|
|
2915
2967
|
// The administration routes: users, groups, permission rules, clients and the
|
|
@@ -3125,6 +3177,10 @@ var SASjsApi = (() => {
|
|
|
3125
3177
|
}
|
|
3126
3178
|
};
|
|
3127
3179
|
var HANDLED_ROUTES = [
|
|
3180
|
+
"GET /SASjsApi/session/{sessionId}",
|
|
3181
|
+
"GET /SASjsApi/session/{sessionId}/log",
|
|
3182
|
+
"GET /SASjsApi/session/{sessionId}/output",
|
|
3183
|
+
"GET /SASjsApi/session/{sessionId}/state",
|
|
3128
3184
|
"POST /SASjsApi/code/lint",
|
|
3129
3185
|
"POST /SASjsApi/code/format",
|
|
3130
3186
|
"GET /SASjsApi/info/authorizedRoutes",
|
|
@@ -3662,13 +3718,50 @@ var SASjsApi = (() => {
|
|
|
3662
3718
|
]
|
|
3663
3719
|
}
|
|
3664
3720
|
},
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3721
|
+
{
|
|
3722
|
+
id: "code-lint-unauthenticated",
|
|
3723
|
+
route: "POST /SASjsApi/code/lint",
|
|
3724
|
+
description: "refuses a caller with no token",
|
|
3725
|
+
request: { body: { code: "data _null_; run;" } },
|
|
3726
|
+
expect: { status: 401, error: "Unauthorized" }
|
|
3727
|
+
},
|
|
3728
|
+
{
|
|
3729
|
+
id: "code-lint-non-string",
|
|
3730
|
+
route: "POST /SASjsApi/code/lint",
|
|
3731
|
+
description: "refuses a code value that is not a string, rather than coercing it",
|
|
3732
|
+
request: {
|
|
3733
|
+
subject: { userId: "user-admin", clientId: "web_app" },
|
|
3734
|
+
body: { code: 123 }
|
|
3735
|
+
},
|
|
3736
|
+
expect: { status: 400, error: '"code" must be a string' }
|
|
3737
|
+
},
|
|
3738
|
+
{
|
|
3739
|
+
id: "code-lint-empty",
|
|
3740
|
+
route: "POST /SASjsApi/code/lint",
|
|
3741
|
+
description: "refuses an empty buffer, which is not the same as a missing one",
|
|
3742
|
+
request: {
|
|
3743
|
+
subject: { userId: "user-admin", clientId: "web_app" },
|
|
3744
|
+
body: { code: "" }
|
|
3745
|
+
},
|
|
3746
|
+
expect: { status: 400, error: '"code" is not allowed to be empty' }
|
|
3747
|
+
},
|
|
3748
|
+
{
|
|
3749
|
+
id: "code-format-unauthenticated",
|
|
3750
|
+
route: "POST /SASjsApi/code/format",
|
|
3751
|
+
description: "refuses a caller with no token",
|
|
3752
|
+
request: { body: { code: "data _null_; run;" } },
|
|
3753
|
+
expect: { status: 401, error: "Unauthorized" }
|
|
3754
|
+
},
|
|
3755
|
+
{
|
|
3756
|
+
id: "code-format-non-string",
|
|
3757
|
+
route: "POST /SASjsApi/code/format",
|
|
3758
|
+
description: "refuses a code value that is not a string",
|
|
3759
|
+
request: {
|
|
3760
|
+
subject: { userId: "user-admin", clientId: "web_app" },
|
|
3761
|
+
body: { code: 123 }
|
|
3762
|
+
},
|
|
3763
|
+
expect: { status: 400, error: '"code" must be a string' }
|
|
3764
|
+
},
|
|
3672
3765
|
{
|
|
3673
3766
|
id: "code-format-adds-the-header",
|
|
3674
3767
|
route: "POST /SASjsApi/code/format",
|
|
@@ -4805,6 +4898,78 @@ var SASjsApi = (() => {
|
|
|
4805
4898
|
}
|
|
4806
4899
|
];
|
|
4807
4900
|
|
|
4901
|
+
// src/corpus/session.ts
|
|
4902
|
+
var ADMIN = { userId: "user-admin", clientId: "web_app" };
|
|
4903
|
+
var RESTRICTED = { userId: "user-restricted", clientId: "web_app" };
|
|
4904
|
+
var SESSION_CORPUS = [
|
|
4905
|
+
{
|
|
4906
|
+
id: "session-summary-own",
|
|
4907
|
+
route: "GET /SASjsApi/session/{sessionId}",
|
|
4908
|
+
description: "answers the owner the summary of their own session",
|
|
4909
|
+
request: { subject: ADMIN, params: { sessionId: "sess-admin" } },
|
|
4910
|
+
expect: {
|
|
4911
|
+
status: 200,
|
|
4912
|
+
body: {
|
|
4913
|
+
sessionId: "sess-admin",
|
|
4914
|
+
state: "completed",
|
|
4915
|
+
pid: 4242,
|
|
4916
|
+
creationTimeStamp: "2026-11-07T09:00:00.000Z",
|
|
4917
|
+
deathTimeStamp: "2026-11-07T09:00:04.000Z",
|
|
4918
|
+
expiresAfterMins: 60
|
|
4919
|
+
}
|
|
4920
|
+
}
|
|
4921
|
+
},
|
|
4922
|
+
{
|
|
4923
|
+
id: "session-summary-as-admin",
|
|
4924
|
+
route: "GET /SASjsApi/session/{sessionId}",
|
|
4925
|
+
description: "answers an administrator another account's session",
|
|
4926
|
+
request: { subject: ADMIN, params: { sessionId: "sess-restricted" } },
|
|
4927
|
+
expect: {
|
|
4928
|
+
status: 200,
|
|
4929
|
+
body: {
|
|
4930
|
+
sessionId: "sess-restricted",
|
|
4931
|
+
state: "running",
|
|
4932
|
+
pid: 4243,
|
|
4933
|
+
creationTimeStamp: "2026-11-07T09:05:00.000Z"
|
|
4934
|
+
}
|
|
4935
|
+
}
|
|
4936
|
+
},
|
|
4937
|
+
{
|
|
4938
|
+
id: "session-log-own",
|
|
4939
|
+
route: "GET /SASjsApi/session/{sessionId}/log",
|
|
4940
|
+
description: "answers the log this session wrote",
|
|
4941
|
+
request: { subject: ADMIN, params: { sessionId: "sess-admin" } },
|
|
4942
|
+
expect: {
|
|
4943
|
+
status: 200,
|
|
4944
|
+
contents: "NOTE: session started\nNOTE: session completed\n"
|
|
4945
|
+
}
|
|
4946
|
+
},
|
|
4947
|
+
{
|
|
4948
|
+
id: "session-log-nothing-written",
|
|
4949
|
+
route: "GET /SASjsApi/session/{sessionId}/log",
|
|
4950
|
+
description: "answers an empty body for a session that has written nothing",
|
|
4951
|
+
request: { subject: ADMIN, params: { sessionId: "sess-silent" } },
|
|
4952
|
+
expect: { status: 200, contents: "" }
|
|
4953
|
+
},
|
|
4954
|
+
{
|
|
4955
|
+
id: "session-output-own",
|
|
4956
|
+
route: "GET /SASjsApi/session/{sessionId}/output",
|
|
4957
|
+
description: "answers the webout this session produced",
|
|
4958
|
+
request: { subject: ADMIN, params: { sessionId: "sess-admin" } },
|
|
4959
|
+
expect: { status: 200, contents: "<html><body>42</body></html>" }
|
|
4960
|
+
},
|
|
4961
|
+
{
|
|
4962
|
+
id: "session-state-own",
|
|
4963
|
+
route: "GET /SASjsApi/session/{sessionId}/state",
|
|
4964
|
+
description: "answers the run time's state for this session",
|
|
4965
|
+
request: { subject: RESTRICTED, params: { sessionId: "sess-restricted" } },
|
|
4966
|
+
expect: {
|
|
4967
|
+
status: 200,
|
|
4968
|
+
body: { state: "running", pid: 4243, lineCount: 3 }
|
|
4969
|
+
}
|
|
4970
|
+
}
|
|
4971
|
+
];
|
|
4972
|
+
|
|
4808
4973
|
// src/corpus/records.ts
|
|
4809
4974
|
var SIGNED_IN_TOKENS = [
|
|
4810
4975
|
{
|
|
@@ -4867,8 +5032,8 @@ var SASjsApi = (() => {
|
|
|
4867
5032
|
}
|
|
4868
5033
|
]
|
|
4869
5034
|
};
|
|
4870
|
-
var
|
|
4871
|
-
var
|
|
5035
|
+
var ADMIN2 = "admin-access";
|
|
5036
|
+
var RESTRICTED2 = "user-access";
|
|
4872
5037
|
var RESTRICTED_UID = "user-restricted";
|
|
4873
5038
|
var ADMIN_UID = "user-admin";
|
|
4874
5039
|
var RECORD_CORPUS = [
|
|
@@ -4878,7 +5043,7 @@ var SASjsApi = (() => {
|
|
|
4878
5043
|
route: "GET /SASjsApi/user",
|
|
4879
5044
|
description: "lists the accounts any signed-in caller may see",
|
|
4880
5045
|
identity: ADMIN_SIGNED_IN,
|
|
4881
|
-
request: { token:
|
|
5046
|
+
request: { token: ADMIN2 },
|
|
4882
5047
|
expect: {
|
|
4883
5048
|
status: 200,
|
|
4884
5049
|
body: [
|
|
@@ -4902,7 +5067,7 @@ var SASjsApi = (() => {
|
|
|
4902
5067
|
route: "GET /SASjsApi/user/{uid}",
|
|
4903
5068
|
description: "returns the caller their own details, with the auto-exec code",
|
|
4904
5069
|
identity: ADMIN_SIGNED_IN,
|
|
4905
|
-
request: { token:
|
|
5070
|
+
request: { token: RESTRICTED2, params: { uid: RESTRICTED_UID } },
|
|
4906
5071
|
expect: {
|
|
4907
5072
|
status: 200,
|
|
4908
5073
|
partial: {
|
|
@@ -4927,7 +5092,7 @@ var SASjsApi = (() => {
|
|
|
4927
5092
|
route: "GET /SASjsApi/user/{uid}",
|
|
4928
5093
|
description: "answers 404 for an identifier no account has",
|
|
4929
5094
|
identity: ADMIN_SIGNED_IN,
|
|
4930
|
-
request: { token:
|
|
5095
|
+
request: { token: ADMIN2, params: { uid: "user-none" } },
|
|
4931
5096
|
expect: { status: 404, error: "User is not found." }
|
|
4932
5097
|
},
|
|
4933
5098
|
{
|
|
@@ -4935,7 +5100,7 @@ var SASjsApi = (() => {
|
|
|
4935
5100
|
route: "GET /SASjsApi/user/by/username/{username}",
|
|
4936
5101
|
description: "finds an account by username",
|
|
4937
5102
|
identity: ADMIN_SIGNED_IN,
|
|
4938
|
-
request: { token:
|
|
5103
|
+
request: { token: ADMIN2, params: { username: "user2" } },
|
|
4939
5104
|
expect: {
|
|
4940
5105
|
status: 200,
|
|
4941
5106
|
partial: { uid: RESTRICTED_UID, username: "user2", isAdmin: false }
|
|
@@ -4954,7 +5119,7 @@ var SASjsApi = (() => {
|
|
|
4954
5119
|
route: "GET /SASjsApi/user/by/username/{username}",
|
|
4955
5120
|
description: "answers 404 for a username no account has",
|
|
4956
5121
|
identity: ADMIN_SIGNED_IN,
|
|
4957
|
-
request: { token:
|
|
5122
|
+
request: { token: ADMIN2, params: { username: "nobody" } },
|
|
4958
5123
|
expect: { status: 404, error: "User is not found." }
|
|
4959
5124
|
},
|
|
4960
5125
|
{
|
|
@@ -4963,7 +5128,7 @@ var SASjsApi = (() => {
|
|
|
4963
5128
|
description: "creates an account, sanitised, and reports it",
|
|
4964
5129
|
identity: ADMIN_SIGNED_IN,
|
|
4965
5130
|
request: {
|
|
4966
|
-
token:
|
|
5131
|
+
token: ADMIN2,
|
|
4967
5132
|
body: {
|
|
4968
5133
|
username: "newuser",
|
|
4969
5134
|
displayName: " New User ",
|
|
@@ -4988,7 +5153,7 @@ var SASjsApi = (() => {
|
|
|
4988
5153
|
description: "refuses a creation by a caller who is not an administrator",
|
|
4989
5154
|
identity: ADMIN_SIGNED_IN,
|
|
4990
5155
|
request: {
|
|
4991
|
-
token:
|
|
5156
|
+
token: RESTRICTED2,
|
|
4992
5157
|
body: {
|
|
4993
5158
|
username: "newuser",
|
|
4994
5159
|
displayName: "New User",
|
|
@@ -5011,7 +5176,7 @@ var SASjsApi = (() => {
|
|
|
5011
5176
|
description: "refuses a username that is taken",
|
|
5012
5177
|
identity: ADMIN_SIGNED_IN,
|
|
5013
5178
|
request: {
|
|
5014
|
-
token:
|
|
5179
|
+
token: ADMIN2,
|
|
5015
5180
|
body: { username: "user2", displayName: "Another", password: "newpass" }
|
|
5016
5181
|
},
|
|
5017
5182
|
expect: { status: 409, error: "Username already exists." }
|
|
@@ -5022,7 +5187,7 @@ var SASjsApi = (() => {
|
|
|
5022
5187
|
description: "changes an account's display name",
|
|
5023
5188
|
identity: ADMIN_SIGNED_IN,
|
|
5024
5189
|
request: {
|
|
5025
|
-
token:
|
|
5190
|
+
token: ADMIN2,
|
|
5026
5191
|
params: { uid: RESTRICTED_UID },
|
|
5027
5192
|
body: {
|
|
5028
5193
|
displayName: "Renamed User",
|
|
@@ -5041,7 +5206,7 @@ var SASjsApi = (() => {
|
|
|
5041
5206
|
description: "refuses a change to somebody else's account",
|
|
5042
5207
|
identity: ADMIN_SIGNED_IN,
|
|
5043
5208
|
request: {
|
|
5044
|
-
token:
|
|
5209
|
+
token: RESTRICTED2,
|
|
5045
5210
|
params: { uid: ADMIN_UID },
|
|
5046
5211
|
body: { displayName: "Hijacked", username: "admin", password: "admin123" }
|
|
5047
5212
|
},
|
|
@@ -5053,7 +5218,7 @@ var SASjsApi = (() => {
|
|
|
5053
5218
|
description: "answers 404 with the identifier it looked up",
|
|
5054
5219
|
identity: ADMIN_SIGNED_IN,
|
|
5055
5220
|
request: {
|
|
5056
|
-
token:
|
|
5221
|
+
token: ADMIN2,
|
|
5057
5222
|
params: { uid: "user-none" },
|
|
5058
5223
|
body: { displayName: "Nobody", username: "nobody", password: "none123" }
|
|
5059
5224
|
},
|
|
@@ -5065,7 +5230,7 @@ var SASjsApi = (() => {
|
|
|
5065
5230
|
description: "refuses a username change on a provider-managed account",
|
|
5066
5231
|
identity: PROVIDER_MANAGED,
|
|
5067
5232
|
request: {
|
|
5068
|
-
token:
|
|
5233
|
+
token: ADMIN2,
|
|
5069
5234
|
params: { uid: "user-directory" },
|
|
5070
5235
|
body: {
|
|
5071
5236
|
username: "renamed",
|
|
@@ -5084,7 +5249,7 @@ var SASjsApi = (() => {
|
|
|
5084
5249
|
description: "refuses a username another account already has",
|
|
5085
5250
|
identity: ADMIN_SIGNED_IN,
|
|
5086
5251
|
request: {
|
|
5087
|
-
token:
|
|
5252
|
+
token: ADMIN2,
|
|
5088
5253
|
params: { uid: RESTRICTED_UID },
|
|
5089
5254
|
body: { username: "admin", displayName: "Demo User", password: "user123" }
|
|
5090
5255
|
},
|
|
@@ -5096,7 +5261,7 @@ var SASjsApi = (() => {
|
|
|
5096
5261
|
description: "changes an account looked up by username",
|
|
5097
5262
|
identity: ADMIN_SIGNED_IN,
|
|
5098
5263
|
request: {
|
|
5099
|
-
token:
|
|
5264
|
+
token: ADMIN2,
|
|
5100
5265
|
params: { username: "user2" },
|
|
5101
5266
|
body: {
|
|
5102
5267
|
isActive: false,
|
|
@@ -5113,7 +5278,7 @@ var SASjsApi = (() => {
|
|
|
5113
5278
|
description: "refuses a change to another account by username",
|
|
5114
5279
|
identity: ADMIN_SIGNED_IN,
|
|
5115
5280
|
request: {
|
|
5116
|
-
token:
|
|
5281
|
+
token: RESTRICTED2,
|
|
5117
5282
|
params: { username: "admin" },
|
|
5118
5283
|
body: { displayName: "Hijacked", username: "admin", password: "admin123" }
|
|
5119
5284
|
},
|
|
@@ -5125,7 +5290,7 @@ var SASjsApi = (() => {
|
|
|
5125
5290
|
description: "answers 404 with the username it looked up",
|
|
5126
5291
|
identity: ADMIN_SIGNED_IN,
|
|
5127
5292
|
request: {
|
|
5128
|
-
token:
|
|
5293
|
+
token: ADMIN2,
|
|
5129
5294
|
params: { username: "nobody" },
|
|
5130
5295
|
body: { displayName: "Nobody", username: "nobody", password: "none123" }
|
|
5131
5296
|
},
|
|
@@ -5137,7 +5302,7 @@ var SASjsApi = (() => {
|
|
|
5137
5302
|
description: "refuses a display-name change on a provider-managed account",
|
|
5138
5303
|
identity: PROVIDER_MANAGED,
|
|
5139
5304
|
request: {
|
|
5140
|
-
token:
|
|
5305
|
+
token: ADMIN2,
|
|
5141
5306
|
params: { username: "diruser" },
|
|
5142
5307
|
body: { displayName: "Renamed", username: "diruser", password: "dir123" }
|
|
5143
5308
|
},
|
|
@@ -5152,7 +5317,7 @@ var SASjsApi = (() => {
|
|
|
5152
5317
|
description: "refuses a username another account already has",
|
|
5153
5318
|
identity: ADMIN_SIGNED_IN,
|
|
5154
5319
|
request: {
|
|
5155
|
-
token:
|
|
5320
|
+
token: ADMIN2,
|
|
5156
5321
|
params: { username: "user2" },
|
|
5157
5322
|
body: { username: "admin", displayName: "Demo User", password: "user123" }
|
|
5158
5323
|
},
|
|
@@ -5163,7 +5328,7 @@ var SASjsApi = (() => {
|
|
|
5163
5328
|
route: "DELETE /SASjsApi/user/{uid}",
|
|
5164
5329
|
description: "deletes an account as an administrator, without a password",
|
|
5165
5330
|
identity: ADMIN_SIGNED_IN,
|
|
5166
|
-
request: { token:
|
|
5331
|
+
request: { token: ADMIN2, params: { uid: RESTRICTED_UID }, body: {} },
|
|
5167
5332
|
expect: { status: 200, body: "Account Deleted!" }
|
|
5168
5333
|
},
|
|
5169
5334
|
{
|
|
@@ -5171,7 +5336,7 @@ var SASjsApi = (() => {
|
|
|
5171
5336
|
route: "DELETE /SASjsApi/user/{uid}",
|
|
5172
5337
|
description: "refuses a deletion of somebody else's account",
|
|
5173
5338
|
identity: ADMIN_SIGNED_IN,
|
|
5174
|
-
request: { token:
|
|
5339
|
+
request: { token: RESTRICTED2, params: { uid: ADMIN_UID }, body: {} },
|
|
5175
5340
|
expect: { status: 401, error: "Admin account required" }
|
|
5176
5341
|
},
|
|
5177
5342
|
{
|
|
@@ -5179,7 +5344,7 @@ var SASjsApi = (() => {
|
|
|
5179
5344
|
route: "DELETE /SASjsApi/user/{uid}",
|
|
5180
5345
|
description: "answers 404 for an identifier no account has",
|
|
5181
5346
|
identity: ADMIN_SIGNED_IN,
|
|
5182
|
-
request: { token:
|
|
5347
|
+
request: { token: ADMIN2, params: { uid: "user-none" }, body: {} },
|
|
5183
5348
|
expect: { status: 404, error: "User is not found." }
|
|
5184
5349
|
},
|
|
5185
5350
|
{
|
|
@@ -5188,7 +5353,7 @@ var SASjsApi = (() => {
|
|
|
5188
5353
|
description: "deletes an account looked up by username",
|
|
5189
5354
|
identity: ADMIN_SIGNED_IN,
|
|
5190
5355
|
request: {
|
|
5191
|
-
token:
|
|
5356
|
+
token: ADMIN2,
|
|
5192
5357
|
params: { username: "user2" },
|
|
5193
5358
|
body: {}
|
|
5194
5359
|
},
|
|
@@ -5200,7 +5365,7 @@ var SASjsApi = (() => {
|
|
|
5200
5365
|
description: "refuses a self-deletion whose password is wrong",
|
|
5201
5366
|
identity: ADMIN_SIGNED_IN,
|
|
5202
5367
|
request: {
|
|
5203
|
-
token:
|
|
5368
|
+
token: RESTRICTED2,
|
|
5204
5369
|
params: { username: "user2" },
|
|
5205
5370
|
body: { password: "wrong123" }
|
|
5206
5371
|
},
|
|
@@ -5211,7 +5376,7 @@ var SASjsApi = (() => {
|
|
|
5211
5376
|
route: "DELETE /SASjsApi/user/by/username/{username}",
|
|
5212
5377
|
description: "answers 404 for a username no account has",
|
|
5213
5378
|
identity: ADMIN_SIGNED_IN,
|
|
5214
|
-
request: { token:
|
|
5379
|
+
request: { token: ADMIN2, params: { username: "nobody" }, body: {} },
|
|
5215
5380
|
expect: { status: 404, error: "User is not found." }
|
|
5216
5381
|
},
|
|
5217
5382
|
// ----------------------------------------------------------------- groups
|
|
@@ -5220,7 +5385,7 @@ var SASjsApi = (() => {
|
|
|
5220
5385
|
route: "GET /SASjsApi/group",
|
|
5221
5386
|
description: "lists the groups",
|
|
5222
5387
|
identity: ADMIN_SIGNED_IN,
|
|
5223
|
-
request: { token:
|
|
5388
|
+
request: { token: RESTRICTED2 },
|
|
5224
5389
|
expect: {
|
|
5225
5390
|
status: 200,
|
|
5226
5391
|
body: [
|
|
@@ -5242,7 +5407,7 @@ var SASjsApi = (() => {
|
|
|
5242
5407
|
route: "GET /SASjsApi/group/{uid}",
|
|
5243
5408
|
description: "returns a group and its members",
|
|
5244
5409
|
identity: ADMIN_SIGNED_IN,
|
|
5245
|
-
request: { token:
|
|
5410
|
+
request: { token: RESTRICTED2, params: { uid: "group-admins" } },
|
|
5246
5411
|
expect: {
|
|
5247
5412
|
status: 200,
|
|
5248
5413
|
partial: {
|
|
@@ -5265,7 +5430,7 @@ var SASjsApi = (() => {
|
|
|
5265
5430
|
route: "GET /SASjsApi/group/{uid}",
|
|
5266
5431
|
description: "answers 404 for an identifier no group has",
|
|
5267
5432
|
identity: ADMIN_SIGNED_IN,
|
|
5268
|
-
request: { token:
|
|
5433
|
+
request: { token: ADMIN2, params: { uid: "group-none" } },
|
|
5269
5434
|
expect: { status: 404, error: "Group not found." }
|
|
5270
5435
|
},
|
|
5271
5436
|
{
|
|
@@ -5273,7 +5438,7 @@ var SASjsApi = (() => {
|
|
|
5273
5438
|
route: "GET /SASjsApi/group/by/groupname/{name}",
|
|
5274
5439
|
description: "finds a group by name",
|
|
5275
5440
|
identity: ADMIN_SIGNED_IN,
|
|
5276
|
-
request: { token:
|
|
5441
|
+
request: { token: ADMIN2, params: { name: "DCGroup" } },
|
|
5277
5442
|
expect: {
|
|
5278
5443
|
status: 200,
|
|
5279
5444
|
partial: { uid: "group-data-controller", name: "DCGroup" }
|
|
@@ -5284,7 +5449,7 @@ var SASjsApi = (() => {
|
|
|
5284
5449
|
route: "GET /SASjsApi/group/by/groupname/{name}",
|
|
5285
5450
|
description: "answers 404 for a name no group has",
|
|
5286
5451
|
identity: ADMIN_SIGNED_IN,
|
|
5287
|
-
request: { token:
|
|
5452
|
+
request: { token: ADMIN2, params: { name: "nope" } },
|
|
5288
5453
|
expect: { status: 404, error: "Group not found." }
|
|
5289
5454
|
},
|
|
5290
5455
|
{
|
|
@@ -5293,7 +5458,7 @@ var SASjsApi = (() => {
|
|
|
5293
5458
|
description: "creates a group with no members",
|
|
5294
5459
|
identity: ADMIN_SIGNED_IN,
|
|
5295
5460
|
request: {
|
|
5296
|
-
token:
|
|
5461
|
+
token: ADMIN2,
|
|
5297
5462
|
body: { name: "NewGroup", description: "A new group", isActive: true }
|
|
5298
5463
|
},
|
|
5299
5464
|
expect: {
|
|
@@ -5312,7 +5477,7 @@ var SASjsApi = (() => {
|
|
|
5312
5477
|
description: "refuses a creation by a caller who is not an administrator",
|
|
5313
5478
|
identity: ADMIN_SIGNED_IN,
|
|
5314
5479
|
request: {
|
|
5315
|
-
token:
|
|
5480
|
+
token: RESTRICTED2,
|
|
5316
5481
|
body: { name: "NewGroup", description: "x" }
|
|
5317
5482
|
},
|
|
5318
5483
|
expect: { status: 401, error: "Admin account required" }
|
|
@@ -5322,7 +5487,7 @@ var SASjsApi = (() => {
|
|
|
5322
5487
|
route: "POST /SASjsApi/group",
|
|
5323
5488
|
description: "refuses a name that is taken",
|
|
5324
5489
|
identity: ADMIN_SIGNED_IN,
|
|
5325
|
-
request: { token:
|
|
5490
|
+
request: { token: ADMIN2, body: { name: "DCGroup", description: "again" } },
|
|
5326
5491
|
expect: { status: 409, error: "Group name already exists." }
|
|
5327
5492
|
},
|
|
5328
5493
|
{
|
|
@@ -5331,7 +5496,7 @@ var SASjsApi = (() => {
|
|
|
5331
5496
|
description: "adds a member and returns the group",
|
|
5332
5497
|
identity: ADMIN_SIGNED_IN,
|
|
5333
5498
|
request: {
|
|
5334
|
-
token:
|
|
5499
|
+
token: ADMIN2,
|
|
5335
5500
|
params: { groupUid: "group-admins", userUid: RESTRICTED_UID }
|
|
5336
5501
|
},
|
|
5337
5502
|
expect: {
|
|
@@ -5345,7 +5510,7 @@ var SASjsApi = (() => {
|
|
|
5345
5510
|
description: "refuses a change to the reserved public group",
|
|
5346
5511
|
identity: PROVIDER_MANAGED,
|
|
5347
5512
|
request: {
|
|
5348
|
-
token:
|
|
5513
|
+
token: ADMIN2,
|
|
5349
5514
|
params: { groupUid: "group-public", userUid: RESTRICTED_UID }
|
|
5350
5515
|
},
|
|
5351
5516
|
expect: { status: 400, error: "Can't add/remove user to 'public' group." }
|
|
@@ -5356,7 +5521,7 @@ var SASjsApi = (() => {
|
|
|
5356
5521
|
description: "refuses a membership change by a non-administrator",
|
|
5357
5522
|
identity: ADMIN_SIGNED_IN,
|
|
5358
5523
|
request: {
|
|
5359
|
-
token:
|
|
5524
|
+
token: RESTRICTED2,
|
|
5360
5525
|
params: { groupUid: "group-admins", userUid: RESTRICTED_UID }
|
|
5361
5526
|
},
|
|
5362
5527
|
expect: { status: 401, error: "Admin account required" }
|
|
@@ -5367,7 +5532,7 @@ var SASjsApi = (() => {
|
|
|
5367
5532
|
description: "answers 404 for a group that does not exist",
|
|
5368
5533
|
identity: ADMIN_SIGNED_IN,
|
|
5369
5534
|
request: {
|
|
5370
|
-
token:
|
|
5535
|
+
token: ADMIN2,
|
|
5371
5536
|
params: { groupUid: "group-none", userUid: RESTRICTED_UID }
|
|
5372
5537
|
},
|
|
5373
5538
|
expect: { status: 404, error: "Group not found." }
|
|
@@ -5378,7 +5543,7 @@ var SASjsApi = (() => {
|
|
|
5378
5543
|
description: "refuses a membership change on a provider-managed group",
|
|
5379
5544
|
identity: PROVIDER_MANAGED,
|
|
5380
5545
|
request: {
|
|
5381
|
-
token:
|
|
5546
|
+
token: ADMIN2,
|
|
5382
5547
|
params: { groupUid: "group-directory", userUid: RESTRICTED_UID }
|
|
5383
5548
|
},
|
|
5384
5549
|
expect: {
|
|
@@ -5392,7 +5557,7 @@ var SASjsApi = (() => {
|
|
|
5392
5557
|
description: "removes a member and returns the group",
|
|
5393
5558
|
identity: ADMIN_SIGNED_IN,
|
|
5394
5559
|
request: {
|
|
5395
|
-
token:
|
|
5560
|
+
token: ADMIN2,
|
|
5396
5561
|
params: { groupUid: "group-data-controller", userUid: RESTRICTED_UID }
|
|
5397
5562
|
},
|
|
5398
5563
|
expect: {
|
|
@@ -5406,7 +5571,7 @@ var SASjsApi = (() => {
|
|
|
5406
5571
|
description: "refuses a membership change for a provider-managed user",
|
|
5407
5572
|
identity: PROVIDER_MANAGED,
|
|
5408
5573
|
request: {
|
|
5409
|
-
token:
|
|
5574
|
+
token: ADMIN2,
|
|
5410
5575
|
params: { groupUid: "group-admins", userUid: "user-directory" }
|
|
5411
5576
|
},
|
|
5412
5577
|
expect: {
|
|
@@ -5420,7 +5585,7 @@ var SASjsApi = (() => {
|
|
|
5420
5585
|
description: "refuses a membership change for a provider-managed user",
|
|
5421
5586
|
identity: PROVIDER_MANAGED,
|
|
5422
5587
|
request: {
|
|
5423
|
-
token:
|
|
5588
|
+
token: ADMIN2,
|
|
5424
5589
|
params: { groupUid: "group-admins", userUid: "user-directory" }
|
|
5425
5590
|
},
|
|
5426
5591
|
expect: {
|
|
@@ -5434,7 +5599,7 @@ var SASjsApi = (() => {
|
|
|
5434
5599
|
description: "refuses a change to the reserved public group",
|
|
5435
5600
|
identity: PROVIDER_MANAGED,
|
|
5436
5601
|
request: {
|
|
5437
|
-
token:
|
|
5602
|
+
token: ADMIN2,
|
|
5438
5603
|
params: { groupUid: "group-public", userUid: RESTRICTED_UID }
|
|
5439
5604
|
},
|
|
5440
5605
|
expect: { status: 400, error: "Can't add/remove user to 'public' group." }
|
|
@@ -5445,7 +5610,7 @@ var SASjsApi = (() => {
|
|
|
5445
5610
|
description: "refuses a membership change by a non-administrator",
|
|
5446
5611
|
identity: ADMIN_SIGNED_IN,
|
|
5447
5612
|
request: {
|
|
5448
|
-
token:
|
|
5613
|
+
token: RESTRICTED2,
|
|
5449
5614
|
params: { groupUid: "group-data-controller", userUid: RESTRICTED_UID }
|
|
5450
5615
|
},
|
|
5451
5616
|
expect: { status: 401, error: "Admin account required" }
|
|
@@ -5456,7 +5621,7 @@ var SASjsApi = (() => {
|
|
|
5456
5621
|
description: "answers 404 for a member that does not exist",
|
|
5457
5622
|
identity: ADMIN_SIGNED_IN,
|
|
5458
5623
|
request: {
|
|
5459
|
-
token:
|
|
5624
|
+
token: ADMIN2,
|
|
5460
5625
|
params: { groupUid: "group-admins", userUid: "user-none" }
|
|
5461
5626
|
},
|
|
5462
5627
|
expect: { status: 404, error: "User not found." }
|
|
@@ -5467,7 +5632,7 @@ var SASjsApi = (() => {
|
|
|
5467
5632
|
description: "refuses a membership change on a provider-managed group",
|
|
5468
5633
|
identity: PROVIDER_MANAGED,
|
|
5469
5634
|
request: {
|
|
5470
|
-
token:
|
|
5635
|
+
token: ADMIN2,
|
|
5471
5636
|
params: { groupUid: "group-directory", userUid: RESTRICTED_UID }
|
|
5472
5637
|
},
|
|
5473
5638
|
expect: {
|
|
@@ -5480,7 +5645,7 @@ var SASjsApi = (() => {
|
|
|
5480
5645
|
route: "DELETE /SASjsApi/group/{uid}",
|
|
5481
5646
|
description: "deletes a group",
|
|
5482
5647
|
identity: ADMIN_SIGNED_IN,
|
|
5483
|
-
request: { token:
|
|
5648
|
+
request: { token: ADMIN2, params: { uid: "group-data-controller" } },
|
|
5484
5649
|
expect: { status: 200 }
|
|
5485
5650
|
},
|
|
5486
5651
|
{
|
|
@@ -5488,7 +5653,7 @@ var SASjsApi = (() => {
|
|
|
5488
5653
|
route: "DELETE /SASjsApi/group/{uid}",
|
|
5489
5654
|
description: "refuses a deletion by a caller who is not an administrator",
|
|
5490
5655
|
identity: ADMIN_SIGNED_IN,
|
|
5491
|
-
request: { token:
|
|
5656
|
+
request: { token: RESTRICTED2, params: { uid: "group-admins" } },
|
|
5492
5657
|
expect: { status: 401, error: "Admin account required" }
|
|
5493
5658
|
},
|
|
5494
5659
|
{
|
|
@@ -5496,7 +5661,7 @@ var SASjsApi = (() => {
|
|
|
5496
5661
|
route: "DELETE /SASjsApi/group/{uid}",
|
|
5497
5662
|
description: "answers 404 for an identifier no group has",
|
|
5498
5663
|
identity: ADMIN_SIGNED_IN,
|
|
5499
|
-
request: { token:
|
|
5664
|
+
request: { token: ADMIN2, params: { uid: "group-none" } },
|
|
5500
5665
|
expect: { status: 404, error: "Group not found." }
|
|
5501
5666
|
},
|
|
5502
5667
|
// ------------------------------------------------------------ permissions
|
|
@@ -5505,7 +5670,7 @@ var SASjsApi = (() => {
|
|
|
5505
5670
|
route: "GET /SASjsApi/info/authorizedRoutes",
|
|
5506
5671
|
description: "answers the routes that accept a rule, to any caller",
|
|
5507
5672
|
identity: ADMIN_SIGNED_IN,
|
|
5508
|
-
request: { token:
|
|
5673
|
+
request: { token: RESTRICTED2 },
|
|
5509
5674
|
expect: {
|
|
5510
5675
|
status: 200,
|
|
5511
5676
|
body: {
|
|
@@ -5529,7 +5694,7 @@ var SASjsApi = (() => {
|
|
|
5529
5694
|
route: "GET /SASjsApi/info/myAuthorizedRoutes",
|
|
5530
5695
|
description: "answers every route to an administrator",
|
|
5531
5696
|
identity: ADMIN_SIGNED_IN,
|
|
5532
|
-
request: { token:
|
|
5697
|
+
request: { token: ADMIN2 },
|
|
5533
5698
|
expect: {
|
|
5534
5699
|
status: 200,
|
|
5535
5700
|
body: {
|
|
@@ -5553,7 +5718,7 @@ var SASjsApi = (() => {
|
|
|
5553
5718
|
route: "GET /SASjsApi/info/myAuthorizedRoutes",
|
|
5554
5719
|
description: "answers a caller only the routes its rules grant",
|
|
5555
5720
|
identity: ADMIN_SIGNED_IN,
|
|
5556
|
-
request: { token:
|
|
5721
|
+
request: { token: RESTRICTED2 },
|
|
5557
5722
|
expect: {
|
|
5558
5723
|
status: 200,
|
|
5559
5724
|
// /AppStream is visible whatever the rules say; the two grants come from
|
|
@@ -5569,7 +5734,7 @@ var SASjsApi = (() => {
|
|
|
5569
5734
|
route: "GET /SASjsApi/permission",
|
|
5570
5735
|
description: "returns every rule to an administrator",
|
|
5571
5736
|
identity: ADMIN_SIGNED_IN,
|
|
5572
|
-
request: { token:
|
|
5737
|
+
request: { token: ADMIN2 },
|
|
5573
5738
|
expect: {
|
|
5574
5739
|
status: 200,
|
|
5575
5740
|
body: [
|
|
@@ -5602,7 +5767,7 @@ var SASjsApi = (() => {
|
|
|
5602
5767
|
route: "GET /SASjsApi/permission",
|
|
5603
5768
|
description: "returns a caller only their own rules and their groups'",
|
|
5604
5769
|
identity: ADMIN_SIGNED_IN,
|
|
5605
|
-
request: { token:
|
|
5770
|
+
request: { token: RESTRICTED2 },
|
|
5606
5771
|
expect: {
|
|
5607
5772
|
status: 200,
|
|
5608
5773
|
body: [
|
|
@@ -5644,7 +5809,7 @@ var SASjsApi = (() => {
|
|
|
5644
5809
|
description: "creates a rule for a user",
|
|
5645
5810
|
identity: ADMIN_SIGNED_IN,
|
|
5646
5811
|
request: {
|
|
5647
|
-
token:
|
|
5812
|
+
token: ADMIN2,
|
|
5648
5813
|
body: {
|
|
5649
5814
|
path: "/SASjsApi/drive/folder",
|
|
5650
5815
|
type: "Route",
|
|
@@ -5664,7 +5829,7 @@ var SASjsApi = (() => {
|
|
|
5664
5829
|
description: "creates a rule for a group",
|
|
5665
5830
|
identity: ADMIN_SIGNED_IN,
|
|
5666
5831
|
request: {
|
|
5667
|
-
token:
|
|
5832
|
+
token: ADMIN2,
|
|
5668
5833
|
body: {
|
|
5669
5834
|
path: "/SASjsApi/drive/rename",
|
|
5670
5835
|
type: "Route",
|
|
@@ -5688,7 +5853,7 @@ var SASjsApi = (() => {
|
|
|
5688
5853
|
description: "refuses a principal type that is neither a user nor a group",
|
|
5689
5854
|
identity: ADMIN_SIGNED_IN,
|
|
5690
5855
|
request: {
|
|
5691
|
-
token:
|
|
5856
|
+
token: ADMIN2,
|
|
5692
5857
|
body: {
|
|
5693
5858
|
path: "/SASjsApi/drive/deploy",
|
|
5694
5859
|
type: "Route",
|
|
@@ -5708,7 +5873,7 @@ var SASjsApi = (() => {
|
|
|
5708
5873
|
description: "refuses a rule assigned to an administrator",
|
|
5709
5874
|
identity: ADMIN_SIGNED_IN,
|
|
5710
5875
|
request: {
|
|
5711
|
-
token:
|
|
5876
|
+
token: ADMIN2,
|
|
5712
5877
|
body: {
|
|
5713
5878
|
path: "/SASjsApi/drive/folder",
|
|
5714
5879
|
type: "Route",
|
|
@@ -5728,7 +5893,7 @@ var SASjsApi = (() => {
|
|
|
5728
5893
|
description: "refuses a creation by a non-administrator",
|
|
5729
5894
|
identity: ADMIN_SIGNED_IN,
|
|
5730
5895
|
request: {
|
|
5731
|
-
token:
|
|
5896
|
+
token: RESTRICTED2,
|
|
5732
5897
|
body: {
|
|
5733
5898
|
path: "/SASjsApi/drive/folder",
|
|
5734
5899
|
type: "Route",
|
|
@@ -5745,7 +5910,7 @@ var SASjsApi = (() => {
|
|
|
5745
5910
|
description: "answers 404 for a principal that does not exist",
|
|
5746
5911
|
identity: ADMIN_SIGNED_IN,
|
|
5747
5912
|
request: {
|
|
5748
|
-
token:
|
|
5913
|
+
token: ADMIN2,
|
|
5749
5914
|
body: {
|
|
5750
5915
|
path: "/SASjsApi/drive/rename",
|
|
5751
5916
|
type: "Route",
|
|
@@ -5762,7 +5927,7 @@ var SASjsApi = (() => {
|
|
|
5762
5927
|
description: "refuses a group rule that already exists",
|
|
5763
5928
|
identity: ADMIN_SIGNED_IN,
|
|
5764
5929
|
request: {
|
|
5765
|
-
token:
|
|
5930
|
+
token: ADMIN2,
|
|
5766
5931
|
body: {
|
|
5767
5932
|
path: "/SASjsApi/drive/file",
|
|
5768
5933
|
type: "Route",
|
|
@@ -5782,7 +5947,7 @@ var SASjsApi = (() => {
|
|
|
5782
5947
|
description: "refuses a rule that already exists",
|
|
5783
5948
|
identity: ADMIN_SIGNED_IN,
|
|
5784
5949
|
request: {
|
|
5785
|
-
token:
|
|
5950
|
+
token: ADMIN2,
|
|
5786
5951
|
body: {
|
|
5787
5952
|
path: "/SASjsApi/code/execute",
|
|
5788
5953
|
type: "Route",
|
|
@@ -5802,7 +5967,7 @@ var SASjsApi = (() => {
|
|
|
5802
5967
|
description: "flips a rule from Deny to Grant",
|
|
5803
5968
|
identity: ADMIN_SIGNED_IN,
|
|
5804
5969
|
request: {
|
|
5805
|
-
token:
|
|
5970
|
+
token: ADMIN2,
|
|
5806
5971
|
params: { uid: "rule-code" },
|
|
5807
5972
|
body: { setting: "Grant" }
|
|
5808
5973
|
},
|
|
@@ -5814,7 +5979,7 @@ var SASjsApi = (() => {
|
|
|
5814
5979
|
description: "refuses a change by a non-administrator",
|
|
5815
5980
|
identity: ADMIN_SIGNED_IN,
|
|
5816
5981
|
request: {
|
|
5817
|
-
token:
|
|
5982
|
+
token: RESTRICTED2,
|
|
5818
5983
|
params: { uid: "rule-code" },
|
|
5819
5984
|
body: { setting: "Grant" }
|
|
5820
5985
|
},
|
|
@@ -5826,7 +5991,7 @@ var SASjsApi = (() => {
|
|
|
5826
5991
|
description: "answers 404 for a rule that does not exist",
|
|
5827
5992
|
identity: ADMIN_SIGNED_IN,
|
|
5828
5993
|
request: {
|
|
5829
|
-
token:
|
|
5994
|
+
token: ADMIN2,
|
|
5830
5995
|
params: { uid: "rule-none" },
|
|
5831
5996
|
body: { setting: "Grant" }
|
|
5832
5997
|
},
|
|
@@ -5837,7 +6002,7 @@ var SASjsApi = (() => {
|
|
|
5837
6002
|
route: "DELETE /SASjsApi/permission/{uid}",
|
|
5838
6003
|
description: "deletes a rule",
|
|
5839
6004
|
identity: ADMIN_SIGNED_IN,
|
|
5840
|
-
request: { token:
|
|
6005
|
+
request: { token: ADMIN2, params: { uid: "rule-code" } },
|
|
5841
6006
|
expect: { status: 200, body: "Permission Deleted!" }
|
|
5842
6007
|
},
|
|
5843
6008
|
{
|
|
@@ -5845,7 +6010,7 @@ var SASjsApi = (() => {
|
|
|
5845
6010
|
route: "DELETE /SASjsApi/permission/{uid}",
|
|
5846
6011
|
description: "refuses a deletion by a non-administrator",
|
|
5847
6012
|
identity: ADMIN_SIGNED_IN,
|
|
5848
|
-
request: { token:
|
|
6013
|
+
request: { token: RESTRICTED2, params: { uid: "rule-code" } },
|
|
5849
6014
|
expect: { status: 401, error: "Admin account required" }
|
|
5850
6015
|
},
|
|
5851
6016
|
{
|
|
@@ -5853,7 +6018,7 @@ var SASjsApi = (() => {
|
|
|
5853
6018
|
route: "DELETE /SASjsApi/permission/{uid}",
|
|
5854
6019
|
description: "answers 404 for a rule that does not exist",
|
|
5855
6020
|
identity: ADMIN_SIGNED_IN,
|
|
5856
|
-
request: { token:
|
|
6021
|
+
request: { token: ADMIN2, params: { uid: "rule-none" } },
|
|
5857
6022
|
expect: { status: 404, error: "Permission not found." }
|
|
5858
6023
|
},
|
|
5859
6024
|
// --------------------------------------------------------------- clients
|
|
@@ -5862,7 +6027,7 @@ var SASjsApi = (() => {
|
|
|
5862
6027
|
route: "GET /SASjsApi/client",
|
|
5863
6028
|
description: "lists the registered clients",
|
|
5864
6029
|
identity: ADMIN_SIGNED_IN,
|
|
5865
|
-
request: { token:
|
|
6030
|
+
request: { token: ADMIN2 },
|
|
5866
6031
|
expect: {
|
|
5867
6032
|
status: 200,
|
|
5868
6033
|
body: [
|
|
@@ -5886,7 +6051,7 @@ var SASjsApi = (() => {
|
|
|
5886
6051
|
route: "GET /SASjsApi/client",
|
|
5887
6052
|
description: "refuses the list to a caller who is not an administrator",
|
|
5888
6053
|
identity: ADMIN_SIGNED_IN,
|
|
5889
|
-
request: { token:
|
|
6054
|
+
request: { token: RESTRICTED2 },
|
|
5890
6055
|
expect: { status: 401, error: "Admin account required" }
|
|
5891
6056
|
},
|
|
5892
6057
|
{
|
|
@@ -5895,7 +6060,7 @@ var SASjsApi = (() => {
|
|
|
5895
6060
|
description: "registers a client",
|
|
5896
6061
|
identity: ADMIN_SIGNED_IN,
|
|
5897
6062
|
request: {
|
|
5898
|
-
token:
|
|
6063
|
+
token: ADMIN2,
|
|
5899
6064
|
body: {
|
|
5900
6065
|
clientId: "new_app",
|
|
5901
6066
|
clientSecret: "new_secret",
|
|
@@ -5919,7 +6084,7 @@ var SASjsApi = (() => {
|
|
|
5919
6084
|
description: "applies the schema defaults when the lifetimes are omitted",
|
|
5920
6085
|
identity: ADMIN_SIGNED_IN,
|
|
5921
6086
|
request: {
|
|
5922
|
-
token:
|
|
6087
|
+
token: ADMIN2,
|
|
5923
6088
|
body: { clientId: "default_app", clientSecret: "default_secret" }
|
|
5924
6089
|
},
|
|
5925
6090
|
expect: {
|
|
@@ -5938,7 +6103,7 @@ var SASjsApi = (() => {
|
|
|
5938
6103
|
description: "refuses a registration by a non-administrator",
|
|
5939
6104
|
identity: ADMIN_SIGNED_IN,
|
|
5940
6105
|
request: {
|
|
5941
|
-
token:
|
|
6106
|
+
token: RESTRICTED2,
|
|
5942
6107
|
body: {
|
|
5943
6108
|
clientId: "new_app",
|
|
5944
6109
|
clientSecret: "new_secret",
|
|
@@ -5954,7 +6119,7 @@ var SASjsApi = (() => {
|
|
|
5954
6119
|
description: "refuses a client id that is registered, with the 403 the server sends",
|
|
5955
6120
|
identity: ADMIN_SIGNED_IN,
|
|
5956
6121
|
request: {
|
|
5957
|
-
token:
|
|
6122
|
+
token: ADMIN2,
|
|
5958
6123
|
body: {
|
|
5959
6124
|
clientId: "web_app",
|
|
5960
6125
|
clientSecret: "other",
|
|
@@ -5971,7 +6136,7 @@ var SASjsApi = (() => {
|
|
|
5971
6136
|
description: "changes the caller’s own password",
|
|
5972
6137
|
identity: ADMIN_SIGNED_IN,
|
|
5973
6138
|
request: {
|
|
5974
|
-
token:
|
|
6139
|
+
token: RESTRICTED2,
|
|
5975
6140
|
body: { currentPassword: "user123", newPassword: "changed123" }
|
|
5976
6141
|
},
|
|
5977
6142
|
expect: { status: 204 }
|
|
@@ -5981,7 +6146,7 @@ var SASjsApi = (() => {
|
|
|
5981
6146
|
route: "PATCH /SASjsApi/auth/updatePassword",
|
|
5982
6147
|
description: "refuses a body without the current password",
|
|
5983
6148
|
identity: ADMIN_SIGNED_IN,
|
|
5984
|
-
request: { token:
|
|
6149
|
+
request: { token: RESTRICTED2, body: { newPassword: "changed123" } },
|
|
5985
6150
|
expect: { status: 400, error: '"currentPassword" is required' }
|
|
5986
6151
|
},
|
|
5987
6152
|
{
|
|
@@ -6000,7 +6165,7 @@ var SASjsApi = (() => {
|
|
|
6000
6165
|
description: "refuses a change whose current password is wrong",
|
|
6001
6166
|
identity: ADMIN_SIGNED_IN,
|
|
6002
6167
|
request: {
|
|
6003
|
-
token:
|
|
6168
|
+
token: RESTRICTED2,
|
|
6004
6169
|
body: { currentPassword: "wrong", newPassword: "changed123" }
|
|
6005
6170
|
},
|
|
6006
6171
|
expect: { status: 403, error: "Invalid current password!" }
|
|
@@ -6021,6 +6186,112 @@ var SASjsApi = (() => {
|
|
|
6021
6186
|
}
|
|
6022
6187
|
];
|
|
6023
6188
|
|
|
6189
|
+
// src/session/service.ts
|
|
6190
|
+
var createSessionService = (store, host) => {
|
|
6191
|
+
const notFound = (id) => `Session with ID '${id}' was not found.`;
|
|
6192
|
+
const visible = async (caller, id) => {
|
|
6193
|
+
if (!caller) throw new ApiError(401, "Unauthorized");
|
|
6194
|
+
const reader = await store.userById(
|
|
6195
|
+
caller.userId
|
|
6196
|
+
);
|
|
6197
|
+
if (!reader || !reader.isActive) throw new ApiError(401, "Unauthorized");
|
|
6198
|
+
const session = await host.session(id);
|
|
6199
|
+
if (!session) throw new ApiError(404, notFound(id));
|
|
6200
|
+
const owner = session.owner;
|
|
6201
|
+
if (owner !== reader.uid && owner !== reader.username && !reader.isAdmin)
|
|
6202
|
+
throw new ApiError(404, notFound(id));
|
|
6203
|
+
return session;
|
|
6204
|
+
};
|
|
6205
|
+
return {
|
|
6206
|
+
async summary(caller, id) {
|
|
6207
|
+
const session = await visible(caller, id);
|
|
6208
|
+
return session.summary;
|
|
6209
|
+
},
|
|
6210
|
+
async state(caller, id) {
|
|
6211
|
+
await visible(caller, id);
|
|
6212
|
+
const state = await host.state(id);
|
|
6213
|
+
if (!state) throw new ApiError(404, notFound(id));
|
|
6214
|
+
return state;
|
|
6215
|
+
},
|
|
6216
|
+
async log(caller, id) {
|
|
6217
|
+
await visible(caller, id);
|
|
6218
|
+
const log = await host.log(id);
|
|
6219
|
+
if (log === void 0) throw new ApiError(404, notFound(id));
|
|
6220
|
+
return log;
|
|
6221
|
+
},
|
|
6222
|
+
async output(caller, id) {
|
|
6223
|
+
await visible(caller, id);
|
|
6224
|
+
const output = await host.output(id);
|
|
6225
|
+
if (output === void 0) throw new ApiError(404, notFound(id));
|
|
6226
|
+
return output;
|
|
6227
|
+
}
|
|
6228
|
+
};
|
|
6229
|
+
};
|
|
6230
|
+
|
|
6231
|
+
// src/session/memory-host.ts
|
|
6232
|
+
var DEFAULT_SESSIONS = {
|
|
6233
|
+
"sess-admin": {
|
|
6234
|
+
owner: "user-admin",
|
|
6235
|
+
summary: {
|
|
6236
|
+
sessionId: "sess-admin",
|
|
6237
|
+
state: "completed",
|
|
6238
|
+
pid: 4242,
|
|
6239
|
+
creationTimeStamp: "2026-11-07T09:00:00.000Z",
|
|
6240
|
+
deathTimeStamp: "2026-11-07T09:00:04.000Z",
|
|
6241
|
+
expiresAfterMins: 60
|
|
6242
|
+
}
|
|
6243
|
+
},
|
|
6244
|
+
"sess-restricted": {
|
|
6245
|
+
owner: "user-restricted",
|
|
6246
|
+
summary: {
|
|
6247
|
+
sessionId: "sess-restricted",
|
|
6248
|
+
state: "running",
|
|
6249
|
+
pid: 4243,
|
|
6250
|
+
creationTimeStamp: "2026-11-07T09:05:00.000Z"
|
|
6251
|
+
}
|
|
6252
|
+
},
|
|
6253
|
+
"sess-silent": {
|
|
6254
|
+
owner: "user-admin",
|
|
6255
|
+
summary: {
|
|
6256
|
+
sessionId: "sess-silent",
|
|
6257
|
+
state: "running",
|
|
6258
|
+
pid: 4244,
|
|
6259
|
+
creationTimeStamp: "2026-11-07T09:10:00.000Z"
|
|
6260
|
+
}
|
|
6261
|
+
}
|
|
6262
|
+
};
|
|
6263
|
+
var STATES = {
|
|
6264
|
+
"sess-admin": { state: "completed", pid: 4242, lineCount: 12 },
|
|
6265
|
+
"sess-restricted": { state: "running", pid: 4243, lineCount: 3 }
|
|
6266
|
+
};
|
|
6267
|
+
var LOGS = {
|
|
6268
|
+
"sess-admin": "NOTE: session started\nNOTE: session completed\n",
|
|
6269
|
+
"sess-restricted": "NOTE: session started\n",
|
|
6270
|
+
"sess-silent": ""
|
|
6271
|
+
};
|
|
6272
|
+
var OUTPUTS = {
|
|
6273
|
+
"sess-admin": "<html><body>42</body></html>",
|
|
6274
|
+
"sess-restricted": "",
|
|
6275
|
+
"sess-silent": ""
|
|
6276
|
+
};
|
|
6277
|
+
var MemorySessionHost = class {
|
|
6278
|
+
constructor(sessions = DEFAULT_SESSIONS) {
|
|
6279
|
+
this.sessions = sessions;
|
|
6280
|
+
}
|
|
6281
|
+
async session(id) {
|
|
6282
|
+
return this.sessions[id];
|
|
6283
|
+
}
|
|
6284
|
+
async state(id) {
|
|
6285
|
+
return STATES[id];
|
|
6286
|
+
}
|
|
6287
|
+
async log(id) {
|
|
6288
|
+
return LOGS[id];
|
|
6289
|
+
}
|
|
6290
|
+
async output(id) {
|
|
6291
|
+
return OUTPUTS[id];
|
|
6292
|
+
}
|
|
6293
|
+
};
|
|
6294
|
+
|
|
6024
6295
|
// src/corpus/runner.ts
|
|
6025
6296
|
var servicesFor = (testCase) => {
|
|
6026
6297
|
const identity = new MemoryIdentityStore(
|
|
@@ -6031,7 +6302,8 @@ var SASjsApi = (() => {
|
|
|
6031
6302
|
testCase.unwritable ? new RefusingDriveStore(testCase.seed || {}) : new MemoryDriveStore(testCase.seed || {})
|
|
6032
6303
|
),
|
|
6033
6304
|
identity: createIdentityService(identity),
|
|
6034
|
-
records: createRecordService(identity)
|
|
6305
|
+
records: createRecordService(identity),
|
|
6306
|
+
session: createSessionService(identity, new MemorySessionHost())
|
|
6035
6307
|
};
|
|
6036
6308
|
};
|
|
6037
6309
|
var RefusingDriveStore = class extends MemoryDriveStore {
|