@sasjs/api 0.10.0 → 0.12.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 +557 -108
- package/build/cjs/corpus/code.js +44 -7
- package/build/cjs/corpus/deploy.js +50 -0
- package/build/cjs/corpus/runner.js +6 -1
- package/build/cjs/corpus/session.js +142 -0
- package/build/cjs/drive/registry.js +38 -0
- package/build/cjs/host/dispatch.js +44 -0
- package/build/cjs/index.js +5 -1
- package/build/cjs/routes/generated.js +48 -0
- package/build/cjs/routes/overlay.js +8 -22
- 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/deploy.d.ts +16 -0
- package/build/esm/corpus/deploy.d.ts.map +1 -0
- package/build/esm/corpus/deploy.js +47 -0
- package/build/esm/corpus/runner.d.ts.map +1 -1
- package/build/esm/corpus/runner.js +6 -1
- package/build/esm/corpus/session.d.ts +17 -0
- package/build/esm/corpus/session.d.ts.map +1 -0
- package/build/esm/corpus/session.js +139 -0
- package/build/esm/drive/registry.d.ts +52 -0
- package/build/esm/drive/registry.d.ts.map +1 -0
- package/build/esm/drive/registry.js +33 -0
- package/build/esm/host/dispatch.d.ts +12 -0
- package/build/esm/host/dispatch.d.ts.map +1 -1
- package/build/esm/host/dispatch.js +44 -0
- package/build/esm/index.d.ts +2 -0
- package/build/esm/index.d.ts.map +1 -1
- package/build/esm/index.js +2 -0
- package/build/esm/routes/generated.d.ts.map +1 -1
- package/build/esm/routes/generated.js +48 -0
- package/build/esm/routes/overlay.d.ts.map +1 -1
- package/build/esm/routes/overlay.js +8 -22
- 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.12.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;
|
|
@@ -28,6 +28,7 @@ var SASjsApi = (() => {
|
|
|
28
28
|
CODE_CORPUS: () => CODE_CORPUS,
|
|
29
29
|
DEFAULT_GRANTABLE_ROUTES: () => DEFAULT_GRANTABLE_ROUTES,
|
|
30
30
|
DEFAULT_IDENTITY: () => DEFAULT_IDENTITY,
|
|
31
|
+
DEPLOY_CORPUS: () => DEPLOY_CORPUS,
|
|
31
32
|
DEPLOY_LIMITS: () => DEPLOY_LIMITS,
|
|
32
33
|
DEPLOY_PAYLOAD_BYTES: () => DEPLOY_PAYLOAD_BYTES,
|
|
33
34
|
DEPLOY_SUCCESS: () => DEPLOY_SUCCESS,
|
|
@@ -41,6 +42,7 @@ var SASjsApi = (() => {
|
|
|
41
42
|
PROVIDER_MANAGED: () => PROVIDER_MANAGED,
|
|
42
43
|
RECORD_CORPUS: () => RECORD_CORPUS,
|
|
43
44
|
ROUTES: () => ROUTES,
|
|
45
|
+
SESSION_CORPUS: () => SESSION_CORPUS,
|
|
44
46
|
STATIC_AUTHORIZED_ROUTES: () => STATIC_AUTHORIZED_ROUTES,
|
|
45
47
|
TAG_CAPABILITIES: () => TAG_CAPABILITIES,
|
|
46
48
|
TOP_LEVEL_ROUTES: () => TOP_LEVEL_ROUTES,
|
|
@@ -892,6 +894,14 @@ var SASjsApi = (() => {
|
|
|
892
894
|
{
|
|
893
895
|
status: 200,
|
|
894
896
|
description: "Ok"
|
|
897
|
+
},
|
|
898
|
+
{
|
|
899
|
+
status: 400,
|
|
900
|
+
description: '"code" is required / "code" must be a string / "code" is not allowed to be empty'
|
|
901
|
+
},
|
|
902
|
+
{
|
|
903
|
+
status: 401,
|
|
904
|
+
description: "Unauthorized"
|
|
895
905
|
}
|
|
896
906
|
]
|
|
897
907
|
},
|
|
@@ -920,6 +930,14 @@ var SASjsApi = (() => {
|
|
|
920
930
|
{
|
|
921
931
|
status: 200,
|
|
922
932
|
description: "Ok"
|
|
933
|
+
},
|
|
934
|
+
{
|
|
935
|
+
status: 400,
|
|
936
|
+
description: '"code" is required / "code" must be a string / "code" is not allowed to be empty'
|
|
937
|
+
},
|
|
938
|
+
{
|
|
939
|
+
status: 401,
|
|
940
|
+
description: "Unauthorized"
|
|
923
941
|
}
|
|
924
942
|
]
|
|
925
943
|
},
|
|
@@ -1830,6 +1848,14 @@ var SASjsApi = (() => {
|
|
|
1830
1848
|
{
|
|
1831
1849
|
status: 200,
|
|
1832
1850
|
description: "Ok"
|
|
1851
|
+
},
|
|
1852
|
+
{
|
|
1853
|
+
status: 401,
|
|
1854
|
+
description: "No valid access token or session was supplied"
|
|
1855
|
+
},
|
|
1856
|
+
{
|
|
1857
|
+
status: 404,
|
|
1858
|
+
description: "Session with the given ID was not found."
|
|
1833
1859
|
}
|
|
1834
1860
|
]
|
|
1835
1861
|
},
|
|
@@ -1852,6 +1878,14 @@ var SASjsApi = (() => {
|
|
|
1852
1878
|
{
|
|
1853
1879
|
status: 200,
|
|
1854
1880
|
description: "Ok"
|
|
1881
|
+
},
|
|
1882
|
+
{
|
|
1883
|
+
status: 401,
|
|
1884
|
+
description: "No valid access token or session was supplied"
|
|
1885
|
+
},
|
|
1886
|
+
{
|
|
1887
|
+
status: 404,
|
|
1888
|
+
description: "Session with the given ID was not found."
|
|
1855
1889
|
}
|
|
1856
1890
|
]
|
|
1857
1891
|
},
|
|
@@ -1874,6 +1908,14 @@ var SASjsApi = (() => {
|
|
|
1874
1908
|
{
|
|
1875
1909
|
status: 200,
|
|
1876
1910
|
description: "Ok"
|
|
1911
|
+
},
|
|
1912
|
+
{
|
|
1913
|
+
status: 401,
|
|
1914
|
+
description: "No valid access token or session was supplied"
|
|
1915
|
+
},
|
|
1916
|
+
{
|
|
1917
|
+
status: 404,
|
|
1918
|
+
description: "Session with the given ID was not found."
|
|
1877
1919
|
}
|
|
1878
1920
|
]
|
|
1879
1921
|
},
|
|
@@ -1896,6 +1938,14 @@ var SASjsApi = (() => {
|
|
|
1896
1938
|
{
|
|
1897
1939
|
status: 200,
|
|
1898
1940
|
description: "Ok"
|
|
1941
|
+
},
|
|
1942
|
+
{
|
|
1943
|
+
status: 401,
|
|
1944
|
+
description: "No valid access token or session was supplied"
|
|
1945
|
+
},
|
|
1946
|
+
{
|
|
1947
|
+
status: 404,
|
|
1948
|
+
description: "Session with the given ID was not found."
|
|
1899
1949
|
}
|
|
1900
1950
|
]
|
|
1901
1951
|
},
|
|
@@ -2461,12 +2511,10 @@ var SASjsApi = (() => {
|
|
|
2461
2511
|
};
|
|
2462
2512
|
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
2513
|
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
2514
|
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
2515
|
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
2516
|
var WEB_BUNDLE = "The host serves its own web bundle; there is no API decision here for this package to answer.";
|
|
2468
2517
|
var ARCHIVE = "Expanding the uploaded archive is the host's transport work - multer and a zip library on the server, `DecompressionStream` in a worker - and the host hands this package the tree it produces, which is the same tree `POST /SASjsApi/drive/deploy` takes.";
|
|
2469
|
-
var UNPUBLISH = "Unpublishing inverts the deploy route, so the two land together.";
|
|
2470
2518
|
var success = { status: "success" };
|
|
2471
2519
|
var user = {
|
|
2472
2520
|
uid: "",
|
|
@@ -2600,10 +2648,7 @@ var SASjsApi = (() => {
|
|
|
2600
2648
|
},
|
|
2601
2649
|
// `404` is a pair - the registry name and the appLoc it was published from -
|
|
2602
2650
|
// that matches no entry, and the drive's content is deliberately left alone.
|
|
2603
|
-
"DELETE /SASjsApi/drive/deploy": {
|
|
2604
|
-
implemented: false,
|
|
2605
|
-
reason: UNPUBLISH
|
|
2606
|
-
},
|
|
2651
|
+
"DELETE /SASjsApi/drive/deploy": { implemented: true },
|
|
2607
2652
|
// Group - members and the groups themselves
|
|
2608
2653
|
"GET /SASjsApi/group": { implemented: true },
|
|
2609
2654
|
"GET /SASjsApi/group/{uid}": { implemented: true },
|
|
@@ -2639,22 +2684,13 @@ var SASjsApi = (() => {
|
|
|
2639
2684
|
implemented: true,
|
|
2640
2685
|
responses: { 200: user }
|
|
2641
2686
|
},
|
|
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
|
-
},
|
|
2687
|
+
// The port takes the owner as a uid and falls back to a username, which is
|
|
2688
|
+
// what sasjs/server records today - a host hands its sessions through as they
|
|
2689
|
+
// are, and the comparison tries the identifier first.
|
|
2690
|
+
"GET /SASjsApi/session/{sessionId}": { implemented: true },
|
|
2691
|
+
"GET /SASjsApi/session/{sessionId}/log": { implemented: true },
|
|
2692
|
+
"GET /SASjsApi/session/{sessionId}/output": { implemented: true },
|
|
2693
|
+
"GET /SASjsApi/session/{sessionId}/state": { implemented: true },
|
|
2658
2694
|
// STP - a stored program, on the runtime port
|
|
2659
2695
|
"GET /SASjsApi/stp/execute": { implemented: false, reason: RUNTIME },
|
|
2660
2696
|
"POST /SASjsApi/stp/execute": { implemented: false, reason: RUNTIME },
|
|
@@ -2770,6 +2806,24 @@ var SASjsApi = (() => {
|
|
|
2770
2806
|
return void 0;
|
|
2771
2807
|
};
|
|
2772
2808
|
|
|
2809
|
+
// src/drive/registry.ts
|
|
2810
|
+
var unpublishAppStream = async (registry, body) => {
|
|
2811
|
+
if (!body?.streamServiceName)
|
|
2812
|
+
throw new ApiError(400, '"streamServiceName" is required');
|
|
2813
|
+
if (!body.appLoc) throw new ApiError(400, '"appLoc" is required');
|
|
2814
|
+
if (!await registry.unpublish(body.appLoc))
|
|
2815
|
+
throw new ApiError(404, "No such app stream entry.");
|
|
2816
|
+
return { status: "success" };
|
|
2817
|
+
};
|
|
2818
|
+
var MemoryAppStreamRegistry = class {
|
|
2819
|
+
constructor(folders = ["/Public/myApp"]) {
|
|
2820
|
+
this.folders = new Set(folders);
|
|
2821
|
+
}
|
|
2822
|
+
async unpublish(appLoc) {
|
|
2823
|
+
return this.folders.delete(appLoc);
|
|
2824
|
+
}
|
|
2825
|
+
};
|
|
2826
|
+
|
|
2773
2827
|
// src/host/dispatch.ts
|
|
2774
2828
|
var SECONDS_IN_A_DAY = 86400;
|
|
2775
2829
|
var validate = (route, request) => {
|
|
@@ -2811,6 +2865,14 @@ var SASjsApi = (() => {
|
|
|
2811
2865
|
const query = request.query || {};
|
|
2812
2866
|
const body = request.body || {};
|
|
2813
2867
|
const params = request.params || {};
|
|
2868
|
+
const sessionRequired = () => {
|
|
2869
|
+
if (!services.session)
|
|
2870
|
+
throw new ApiError(
|
|
2871
|
+
501,
|
|
2872
|
+
`This host has no session service, so it cannot answer ${routeId}.`
|
|
2873
|
+
);
|
|
2874
|
+
return services.session;
|
|
2875
|
+
};
|
|
2814
2876
|
const required = () => {
|
|
2815
2877
|
if (!records)
|
|
2816
2878
|
throw new ApiError(
|
|
@@ -2908,8 +2970,55 @@ var SASjsApi = (() => {
|
|
|
2908
2970
|
await drive.deploy(String(body.appLoc ?? ""), body.fileTree);
|
|
2909
2971
|
return { status: 200, body: DEPLOY_SUCCESS };
|
|
2910
2972
|
}
|
|
2973
|
+
case "DELETE /SASjsApi/drive/deploy":
|
|
2974
|
+
if (!services.registry)
|
|
2975
|
+
throw new ApiError(
|
|
2976
|
+
501,
|
|
2977
|
+
`This host has no app stream registry, so it cannot answer ${routeId}.`
|
|
2978
|
+
);
|
|
2979
|
+
return {
|
|
2980
|
+
status: 200,
|
|
2981
|
+
body: await unpublishAppStream(services.registry, body)
|
|
2982
|
+
};
|
|
2911
2983
|
case "GET /SASjsApi/drive/filetree":
|
|
2912
2984
|
return { status: 200, body: await drive.tree(query._folderPath) };
|
|
2985
|
+
// ------------------------------------------------------------- sessions
|
|
2986
|
+
case "GET /SASjsApi/session/{sessionId}": {
|
|
2987
|
+
return {
|
|
2988
|
+
status: 200,
|
|
2989
|
+
body: await sessionRequired().summary(
|
|
2990
|
+
await caller(),
|
|
2991
|
+
String(params.sessionId ?? "")
|
|
2992
|
+
)
|
|
2993
|
+
};
|
|
2994
|
+
}
|
|
2995
|
+
case "GET /SASjsApi/session/{sessionId}/log": {
|
|
2996
|
+
return {
|
|
2997
|
+
status: 200,
|
|
2998
|
+
contents: await sessionRequired().log(
|
|
2999
|
+
await caller(),
|
|
3000
|
+
String(params.sessionId ?? "")
|
|
3001
|
+
)
|
|
3002
|
+
};
|
|
3003
|
+
}
|
|
3004
|
+
case "GET /SASjsApi/session/{sessionId}/output": {
|
|
3005
|
+
return {
|
|
3006
|
+
status: 200,
|
|
3007
|
+
contents: await sessionRequired().output(
|
|
3008
|
+
await caller(),
|
|
3009
|
+
String(params.sessionId ?? "")
|
|
3010
|
+
)
|
|
3011
|
+
};
|
|
3012
|
+
}
|
|
3013
|
+
case "GET /SASjsApi/session/{sessionId}/state": {
|
|
3014
|
+
return {
|
|
3015
|
+
status: 200,
|
|
3016
|
+
body: await sessionRequired().state(
|
|
3017
|
+
await caller(),
|
|
3018
|
+
String(params.sessionId ?? "")
|
|
3019
|
+
)
|
|
3020
|
+
};
|
|
3021
|
+
}
|
|
2913
3022
|
// ------------------------------------------------------------- records
|
|
2914
3023
|
//
|
|
2915
3024
|
// The administration routes: users, groups, permission rules, clients and the
|
|
@@ -3125,6 +3234,11 @@ var SASjsApi = (() => {
|
|
|
3125
3234
|
}
|
|
3126
3235
|
};
|
|
3127
3236
|
var HANDLED_ROUTES = [
|
|
3237
|
+
"DELETE /SASjsApi/drive/deploy",
|
|
3238
|
+
"GET /SASjsApi/session/{sessionId}",
|
|
3239
|
+
"GET /SASjsApi/session/{sessionId}/log",
|
|
3240
|
+
"GET /SASjsApi/session/{sessionId}/output",
|
|
3241
|
+
"GET /SASjsApi/session/{sessionId}/state",
|
|
3128
3242
|
"POST /SASjsApi/code/lint",
|
|
3129
3243
|
"POST /SASjsApi/code/format",
|
|
3130
3244
|
"GET /SASjsApi/info/authorizedRoutes",
|
|
@@ -3662,13 +3776,50 @@ var SASjsApi = (() => {
|
|
|
3662
3776
|
]
|
|
3663
3777
|
}
|
|
3664
3778
|
},
|
|
3665
|
-
|
|
3666
|
-
|
|
3667
|
-
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3671
|
-
|
|
3779
|
+
{
|
|
3780
|
+
id: "code-lint-unauthenticated",
|
|
3781
|
+
route: "POST /SASjsApi/code/lint",
|
|
3782
|
+
description: "refuses a caller with no token",
|
|
3783
|
+
request: { body: { code: "data _null_; run;" } },
|
|
3784
|
+
expect: { status: 401, error: "Unauthorized" }
|
|
3785
|
+
},
|
|
3786
|
+
{
|
|
3787
|
+
id: "code-lint-non-string",
|
|
3788
|
+
route: "POST /SASjsApi/code/lint",
|
|
3789
|
+
description: "refuses a code value that is not a string, rather than coercing it",
|
|
3790
|
+
request: {
|
|
3791
|
+
subject: { userId: "user-admin", clientId: "web_app" },
|
|
3792
|
+
body: { code: 123 }
|
|
3793
|
+
},
|
|
3794
|
+
expect: { status: 400, error: '"code" must be a string' }
|
|
3795
|
+
},
|
|
3796
|
+
{
|
|
3797
|
+
id: "code-lint-empty",
|
|
3798
|
+
route: "POST /SASjsApi/code/lint",
|
|
3799
|
+
description: "refuses an empty buffer, which is not the same as a missing one",
|
|
3800
|
+
request: {
|
|
3801
|
+
subject: { userId: "user-admin", clientId: "web_app" },
|
|
3802
|
+
body: { code: "" }
|
|
3803
|
+
},
|
|
3804
|
+
expect: { status: 400, error: '"code" is not allowed to be empty' }
|
|
3805
|
+
},
|
|
3806
|
+
{
|
|
3807
|
+
id: "code-format-unauthenticated",
|
|
3808
|
+
route: "POST /SASjsApi/code/format",
|
|
3809
|
+
description: "refuses a caller with no token",
|
|
3810
|
+
request: { body: { code: "data _null_; run;" } },
|
|
3811
|
+
expect: { status: 401, error: "Unauthorized" }
|
|
3812
|
+
},
|
|
3813
|
+
{
|
|
3814
|
+
id: "code-format-non-string",
|
|
3815
|
+
route: "POST /SASjsApi/code/format",
|
|
3816
|
+
description: "refuses a code value that is not a string",
|
|
3817
|
+
request: {
|
|
3818
|
+
subject: { userId: "user-admin", clientId: "web_app" },
|
|
3819
|
+
body: { code: 123 }
|
|
3820
|
+
},
|
|
3821
|
+
expect: { status: 400, error: '"code" must be a string' }
|
|
3822
|
+
},
|
|
3672
3823
|
{
|
|
3673
3824
|
id: "code-format-adds-the-header",
|
|
3674
3825
|
route: "POST /SASjsApi/code/format",
|
|
@@ -4805,6 +4956,196 @@ var SASjsApi = (() => {
|
|
|
4805
4956
|
}
|
|
4806
4957
|
];
|
|
4807
4958
|
|
|
4959
|
+
// src/corpus/deploy.ts
|
|
4960
|
+
var SUBJECT = { userId: "user-admin", clientId: "web_app" };
|
|
4961
|
+
var DEPLOY_CORPUS = [
|
|
4962
|
+
{
|
|
4963
|
+
id: "deploy-unpublish",
|
|
4964
|
+
route: "DELETE /SASjsApi/drive/deploy",
|
|
4965
|
+
description: "removes a published app stream and answers the status",
|
|
4966
|
+
request: {
|
|
4967
|
+
subject: SUBJECT,
|
|
4968
|
+
body: { streamServiceName: "myApp", appLoc: "/Public/myApp" }
|
|
4969
|
+
},
|
|
4970
|
+
expect: { status: 200, body: { status: "success" } }
|
|
4971
|
+
},
|
|
4972
|
+
{
|
|
4973
|
+
id: "deploy-unpublish-other-name",
|
|
4974
|
+
route: "DELETE /SASjsApi/drive/deploy",
|
|
4975
|
+
description: "removes the app by its folder when the name has been renamed",
|
|
4976
|
+
request: {
|
|
4977
|
+
subject: SUBJECT,
|
|
4978
|
+
body: { streamServiceName: "renamed-app", appLoc: "/Public/myApp" }
|
|
4979
|
+
},
|
|
4980
|
+
expect: { status: 200, body: { status: "success" } }
|
|
4981
|
+
},
|
|
4982
|
+
{
|
|
4983
|
+
id: "deploy-unpublish-no-stream-name",
|
|
4984
|
+
route: "DELETE /SASjsApi/drive/deploy",
|
|
4985
|
+
description: "refuses a body that does not say which stream to remove",
|
|
4986
|
+
request: { subject: SUBJECT, body: { appLoc: "/Public/myApp" } },
|
|
4987
|
+
expect: { status: 400, error: '"streamServiceName" is required' }
|
|
4988
|
+
},
|
|
4989
|
+
{
|
|
4990
|
+
id: "deploy-unpublish-no-app-loc",
|
|
4991
|
+
route: "DELETE /SASjsApi/drive/deploy",
|
|
4992
|
+
description: "refuses a body that does not say which folder to remove",
|
|
4993
|
+
request: { subject: SUBJECT, body: { streamServiceName: "myApp" } },
|
|
4994
|
+
expect: { status: 400, error: '"appLoc" is required' }
|
|
4995
|
+
},
|
|
4996
|
+
{
|
|
4997
|
+
id: "deploy-unpublish-unknown-folder",
|
|
4998
|
+
route: "DELETE /SASjsApi/drive/deploy",
|
|
4999
|
+
description: "answers 404 for a folder nothing is published at",
|
|
5000
|
+
request: {
|
|
5001
|
+
subject: SUBJECT,
|
|
5002
|
+
body: { streamServiceName: "myApp", appLoc: "/Public/not-an-app" }
|
|
5003
|
+
},
|
|
5004
|
+
expect: { status: 404, error: "No such app stream entry." }
|
|
5005
|
+
}
|
|
5006
|
+
];
|
|
5007
|
+
|
|
5008
|
+
// src/corpus/session.ts
|
|
5009
|
+
var ADMIN = { userId: "user-admin", clientId: "web_app" };
|
|
5010
|
+
var RESTRICTED = { userId: "user-restricted", clientId: "web_app" };
|
|
5011
|
+
var notFound = (id) => `Session with ID '${id}' was not found.`;
|
|
5012
|
+
var UNAUTHORIZED = "Unauthorized";
|
|
5013
|
+
var SESSION_CORPUS = [
|
|
5014
|
+
// ---------------------------------------------------------------- summary
|
|
5015
|
+
{
|
|
5016
|
+
id: "session-summary-own",
|
|
5017
|
+
route: "GET /SASjsApi/session/{sessionId}",
|
|
5018
|
+
description: "answers the owner the summary of their own session",
|
|
5019
|
+
request: { subject: ADMIN, params: { sessionId: "sess-admin" } },
|
|
5020
|
+
expect: {
|
|
5021
|
+
status: 200,
|
|
5022
|
+
body: {
|
|
5023
|
+
sessionId: "sess-admin",
|
|
5024
|
+
state: "completed",
|
|
5025
|
+
pid: 4242,
|
|
5026
|
+
creationTimeStamp: "2026-11-07T09:00:00.000Z",
|
|
5027
|
+
deathTimeStamp: "2026-11-07T09:00:04.000Z",
|
|
5028
|
+
expiresAfterMins: 60
|
|
5029
|
+
}
|
|
5030
|
+
}
|
|
5031
|
+
},
|
|
5032
|
+
{
|
|
5033
|
+
id: "session-summary-as-admin",
|
|
5034
|
+
route: "GET /SASjsApi/session/{sessionId}",
|
|
5035
|
+
description: "answers an administrator another account's session",
|
|
5036
|
+
request: { subject: ADMIN, params: { sessionId: "sess-restricted" } },
|
|
5037
|
+
expect: {
|
|
5038
|
+
status: 200,
|
|
5039
|
+
body: {
|
|
5040
|
+
sessionId: "sess-restricted",
|
|
5041
|
+
state: "running",
|
|
5042
|
+
pid: 4243,
|
|
5043
|
+
creationTimeStamp: "2026-11-07T09:05:00.000Z"
|
|
5044
|
+
}
|
|
5045
|
+
}
|
|
5046
|
+
},
|
|
5047
|
+
{
|
|
5048
|
+
id: "session-summary-unauthenticated",
|
|
5049
|
+
route: "GET /SASjsApi/session/{sessionId}",
|
|
5050
|
+
description: "refuses a caller with no token",
|
|
5051
|
+
request: { params: { sessionId: "sess-admin" } },
|
|
5052
|
+
expect: { status: 401, error: UNAUTHORIZED }
|
|
5053
|
+
},
|
|
5054
|
+
{
|
|
5055
|
+
id: "session-summary-foreign",
|
|
5056
|
+
route: "GET /SASjsApi/session/{sessionId}",
|
|
5057
|
+
description: "answers 404 for another account's session, not 403",
|
|
5058
|
+
request: { subject: RESTRICTED, params: { sessionId: "sess-admin" } },
|
|
5059
|
+
expect: { status: 404, error: notFound("sess-admin") }
|
|
5060
|
+
},
|
|
5061
|
+
{
|
|
5062
|
+
id: "session-summary-unknown",
|
|
5063
|
+
route: "GET /SASjsApi/session/{sessionId}",
|
|
5064
|
+
description: "answers the same 404 for a session that does not exist",
|
|
5065
|
+
request: { subject: ADMIN, params: { sessionId: "sess-nope" } },
|
|
5066
|
+
expect: { status: 404, error: notFound("sess-nope") }
|
|
5067
|
+
},
|
|
5068
|
+
// -------------------------------------------------------------------- log
|
|
5069
|
+
{
|
|
5070
|
+
id: "session-log-own",
|
|
5071
|
+
route: "GET /SASjsApi/session/{sessionId}/log",
|
|
5072
|
+
description: "answers the log this session wrote",
|
|
5073
|
+
request: { subject: ADMIN, params: { sessionId: "sess-admin" } },
|
|
5074
|
+
expect: {
|
|
5075
|
+
status: 200,
|
|
5076
|
+
contents: "NOTE: session started\nNOTE: session completed\n"
|
|
5077
|
+
}
|
|
5078
|
+
},
|
|
5079
|
+
{
|
|
5080
|
+
id: "session-log-nothing-written",
|
|
5081
|
+
route: "GET /SASjsApi/session/{sessionId}/log",
|
|
5082
|
+
description: "answers an empty body for a session that has written nothing",
|
|
5083
|
+
request: { subject: ADMIN, params: { sessionId: "sess-silent" } },
|
|
5084
|
+
expect: { status: 200, contents: "" }
|
|
5085
|
+
},
|
|
5086
|
+
{
|
|
5087
|
+
id: "session-log-unauthenticated",
|
|
5088
|
+
route: "GET /SASjsApi/session/{sessionId}/log",
|
|
5089
|
+
description: "refuses a caller with no token",
|
|
5090
|
+
request: { params: { sessionId: "sess-admin" } },
|
|
5091
|
+
expect: { status: 401, error: UNAUTHORIZED }
|
|
5092
|
+
},
|
|
5093
|
+
{
|
|
5094
|
+
id: "session-log-foreign",
|
|
5095
|
+
route: "GET /SASjsApi/session/{sessionId}/log",
|
|
5096
|
+
description: "will not read another account's log",
|
|
5097
|
+
request: { subject: RESTRICTED, params: { sessionId: "sess-admin" } },
|
|
5098
|
+
expect: { status: 404, error: notFound("sess-admin") }
|
|
5099
|
+
},
|
|
5100
|
+
// ----------------------------------------------------------------- output
|
|
5101
|
+
{
|
|
5102
|
+
id: "session-output-own",
|
|
5103
|
+
route: "GET /SASjsApi/session/{sessionId}/output",
|
|
5104
|
+
description: "answers the webout this session produced",
|
|
5105
|
+
request: { subject: ADMIN, params: { sessionId: "sess-admin" } },
|
|
5106
|
+
expect: { status: 200, contents: "<html><body>42</body></html>" }
|
|
5107
|
+
},
|
|
5108
|
+
{
|
|
5109
|
+
id: "session-output-unauthenticated",
|
|
5110
|
+
route: "GET /SASjsApi/session/{sessionId}/output",
|
|
5111
|
+
description: "refuses a caller with no token",
|
|
5112
|
+
request: { params: { sessionId: "sess-admin" } },
|
|
5113
|
+
expect: { status: 401, error: UNAUTHORIZED }
|
|
5114
|
+
},
|
|
5115
|
+
{
|
|
5116
|
+
id: "session-output-foreign",
|
|
5117
|
+
route: "GET /SASjsApi/session/{sessionId}/output",
|
|
5118
|
+
description: "will not read another account's webout",
|
|
5119
|
+
request: { subject: RESTRICTED, params: { sessionId: "sess-admin" } },
|
|
5120
|
+
expect: { status: 404, error: notFound("sess-admin") }
|
|
5121
|
+
},
|
|
5122
|
+
// ------------------------------------------------------------------ state
|
|
5123
|
+
{
|
|
5124
|
+
id: "session-state-own",
|
|
5125
|
+
route: "GET /SASjsApi/session/{sessionId}/state",
|
|
5126
|
+
description: "answers the run time's state for this session",
|
|
5127
|
+
request: { subject: RESTRICTED, params: { sessionId: "sess-restricted" } },
|
|
5128
|
+
expect: {
|
|
5129
|
+
status: 200,
|
|
5130
|
+
body: { state: "running", pid: 4243, lineCount: 3 }
|
|
5131
|
+
}
|
|
5132
|
+
},
|
|
5133
|
+
{
|
|
5134
|
+
id: "session-state-unauthenticated",
|
|
5135
|
+
route: "GET /SASjsApi/session/{sessionId}/state",
|
|
5136
|
+
description: "refuses a caller with no token",
|
|
5137
|
+
request: { params: { sessionId: "sess-restricted" } },
|
|
5138
|
+
expect: { status: 401, error: UNAUTHORIZED }
|
|
5139
|
+
},
|
|
5140
|
+
{
|
|
5141
|
+
id: "session-state-foreign",
|
|
5142
|
+
route: "GET /SASjsApi/session/{sessionId}/state",
|
|
5143
|
+
description: "will not report another account's session state",
|
|
5144
|
+
request: { subject: RESTRICTED, params: { sessionId: "sess-admin" } },
|
|
5145
|
+
expect: { status: 404, error: notFound("sess-admin") }
|
|
5146
|
+
}
|
|
5147
|
+
];
|
|
5148
|
+
|
|
4808
5149
|
// src/corpus/records.ts
|
|
4809
5150
|
var SIGNED_IN_TOKENS = [
|
|
4810
5151
|
{
|
|
@@ -4867,8 +5208,8 @@ var SASjsApi = (() => {
|
|
|
4867
5208
|
}
|
|
4868
5209
|
]
|
|
4869
5210
|
};
|
|
4870
|
-
var
|
|
4871
|
-
var
|
|
5211
|
+
var ADMIN2 = "admin-access";
|
|
5212
|
+
var RESTRICTED2 = "user-access";
|
|
4872
5213
|
var RESTRICTED_UID = "user-restricted";
|
|
4873
5214
|
var ADMIN_UID = "user-admin";
|
|
4874
5215
|
var RECORD_CORPUS = [
|
|
@@ -4878,7 +5219,7 @@ var SASjsApi = (() => {
|
|
|
4878
5219
|
route: "GET /SASjsApi/user",
|
|
4879
5220
|
description: "lists the accounts any signed-in caller may see",
|
|
4880
5221
|
identity: ADMIN_SIGNED_IN,
|
|
4881
|
-
request: { token:
|
|
5222
|
+
request: { token: ADMIN2 },
|
|
4882
5223
|
expect: {
|
|
4883
5224
|
status: 200,
|
|
4884
5225
|
body: [
|
|
@@ -4902,7 +5243,7 @@ var SASjsApi = (() => {
|
|
|
4902
5243
|
route: "GET /SASjsApi/user/{uid}",
|
|
4903
5244
|
description: "returns the caller their own details, with the auto-exec code",
|
|
4904
5245
|
identity: ADMIN_SIGNED_IN,
|
|
4905
|
-
request: { token:
|
|
5246
|
+
request: { token: RESTRICTED2, params: { uid: RESTRICTED_UID } },
|
|
4906
5247
|
expect: {
|
|
4907
5248
|
status: 200,
|
|
4908
5249
|
partial: {
|
|
@@ -4927,7 +5268,7 @@ var SASjsApi = (() => {
|
|
|
4927
5268
|
route: "GET /SASjsApi/user/{uid}",
|
|
4928
5269
|
description: "answers 404 for an identifier no account has",
|
|
4929
5270
|
identity: ADMIN_SIGNED_IN,
|
|
4930
|
-
request: { token:
|
|
5271
|
+
request: { token: ADMIN2, params: { uid: "user-none" } },
|
|
4931
5272
|
expect: { status: 404, error: "User is not found." }
|
|
4932
5273
|
},
|
|
4933
5274
|
{
|
|
@@ -4935,7 +5276,7 @@ var SASjsApi = (() => {
|
|
|
4935
5276
|
route: "GET /SASjsApi/user/by/username/{username}",
|
|
4936
5277
|
description: "finds an account by username",
|
|
4937
5278
|
identity: ADMIN_SIGNED_IN,
|
|
4938
|
-
request: { token:
|
|
5279
|
+
request: { token: ADMIN2, params: { username: "user2" } },
|
|
4939
5280
|
expect: {
|
|
4940
5281
|
status: 200,
|
|
4941
5282
|
partial: { uid: RESTRICTED_UID, username: "user2", isAdmin: false }
|
|
@@ -4954,7 +5295,7 @@ var SASjsApi = (() => {
|
|
|
4954
5295
|
route: "GET /SASjsApi/user/by/username/{username}",
|
|
4955
5296
|
description: "answers 404 for a username no account has",
|
|
4956
5297
|
identity: ADMIN_SIGNED_IN,
|
|
4957
|
-
request: { token:
|
|
5298
|
+
request: { token: ADMIN2, params: { username: "nobody" } },
|
|
4958
5299
|
expect: { status: 404, error: "User is not found." }
|
|
4959
5300
|
},
|
|
4960
5301
|
{
|
|
@@ -4963,7 +5304,7 @@ var SASjsApi = (() => {
|
|
|
4963
5304
|
description: "creates an account, sanitised, and reports it",
|
|
4964
5305
|
identity: ADMIN_SIGNED_IN,
|
|
4965
5306
|
request: {
|
|
4966
|
-
token:
|
|
5307
|
+
token: ADMIN2,
|
|
4967
5308
|
body: {
|
|
4968
5309
|
username: "newuser",
|
|
4969
5310
|
displayName: " New User ",
|
|
@@ -4988,7 +5329,7 @@ var SASjsApi = (() => {
|
|
|
4988
5329
|
description: "refuses a creation by a caller who is not an administrator",
|
|
4989
5330
|
identity: ADMIN_SIGNED_IN,
|
|
4990
5331
|
request: {
|
|
4991
|
-
token:
|
|
5332
|
+
token: RESTRICTED2,
|
|
4992
5333
|
body: {
|
|
4993
5334
|
username: "newuser",
|
|
4994
5335
|
displayName: "New User",
|
|
@@ -5011,7 +5352,7 @@ var SASjsApi = (() => {
|
|
|
5011
5352
|
description: "refuses a username that is taken",
|
|
5012
5353
|
identity: ADMIN_SIGNED_IN,
|
|
5013
5354
|
request: {
|
|
5014
|
-
token:
|
|
5355
|
+
token: ADMIN2,
|
|
5015
5356
|
body: { username: "user2", displayName: "Another", password: "newpass" }
|
|
5016
5357
|
},
|
|
5017
5358
|
expect: { status: 409, error: "Username already exists." }
|
|
@@ -5022,7 +5363,7 @@ var SASjsApi = (() => {
|
|
|
5022
5363
|
description: "changes an account's display name",
|
|
5023
5364
|
identity: ADMIN_SIGNED_IN,
|
|
5024
5365
|
request: {
|
|
5025
|
-
token:
|
|
5366
|
+
token: ADMIN2,
|
|
5026
5367
|
params: { uid: RESTRICTED_UID },
|
|
5027
5368
|
body: {
|
|
5028
5369
|
displayName: "Renamed User",
|
|
@@ -5041,7 +5382,7 @@ var SASjsApi = (() => {
|
|
|
5041
5382
|
description: "refuses a change to somebody else's account",
|
|
5042
5383
|
identity: ADMIN_SIGNED_IN,
|
|
5043
5384
|
request: {
|
|
5044
|
-
token:
|
|
5385
|
+
token: RESTRICTED2,
|
|
5045
5386
|
params: { uid: ADMIN_UID },
|
|
5046
5387
|
body: { displayName: "Hijacked", username: "admin", password: "admin123" }
|
|
5047
5388
|
},
|
|
@@ -5053,7 +5394,7 @@ var SASjsApi = (() => {
|
|
|
5053
5394
|
description: "answers 404 with the identifier it looked up",
|
|
5054
5395
|
identity: ADMIN_SIGNED_IN,
|
|
5055
5396
|
request: {
|
|
5056
|
-
token:
|
|
5397
|
+
token: ADMIN2,
|
|
5057
5398
|
params: { uid: "user-none" },
|
|
5058
5399
|
body: { displayName: "Nobody", username: "nobody", password: "none123" }
|
|
5059
5400
|
},
|
|
@@ -5065,7 +5406,7 @@ var SASjsApi = (() => {
|
|
|
5065
5406
|
description: "refuses a username change on a provider-managed account",
|
|
5066
5407
|
identity: PROVIDER_MANAGED,
|
|
5067
5408
|
request: {
|
|
5068
|
-
token:
|
|
5409
|
+
token: ADMIN2,
|
|
5069
5410
|
params: { uid: "user-directory" },
|
|
5070
5411
|
body: {
|
|
5071
5412
|
username: "renamed",
|
|
@@ -5084,7 +5425,7 @@ var SASjsApi = (() => {
|
|
|
5084
5425
|
description: "refuses a username another account already has",
|
|
5085
5426
|
identity: ADMIN_SIGNED_IN,
|
|
5086
5427
|
request: {
|
|
5087
|
-
token:
|
|
5428
|
+
token: ADMIN2,
|
|
5088
5429
|
params: { uid: RESTRICTED_UID },
|
|
5089
5430
|
body: { username: "admin", displayName: "Demo User", password: "user123" }
|
|
5090
5431
|
},
|
|
@@ -5096,7 +5437,7 @@ var SASjsApi = (() => {
|
|
|
5096
5437
|
description: "changes an account looked up by username",
|
|
5097
5438
|
identity: ADMIN_SIGNED_IN,
|
|
5098
5439
|
request: {
|
|
5099
|
-
token:
|
|
5440
|
+
token: ADMIN2,
|
|
5100
5441
|
params: { username: "user2" },
|
|
5101
5442
|
body: {
|
|
5102
5443
|
isActive: false,
|
|
@@ -5113,7 +5454,7 @@ var SASjsApi = (() => {
|
|
|
5113
5454
|
description: "refuses a change to another account by username",
|
|
5114
5455
|
identity: ADMIN_SIGNED_IN,
|
|
5115
5456
|
request: {
|
|
5116
|
-
token:
|
|
5457
|
+
token: RESTRICTED2,
|
|
5117
5458
|
params: { username: "admin" },
|
|
5118
5459
|
body: { displayName: "Hijacked", username: "admin", password: "admin123" }
|
|
5119
5460
|
},
|
|
@@ -5125,7 +5466,7 @@ var SASjsApi = (() => {
|
|
|
5125
5466
|
description: "answers 404 with the username it looked up",
|
|
5126
5467
|
identity: ADMIN_SIGNED_IN,
|
|
5127
5468
|
request: {
|
|
5128
|
-
token:
|
|
5469
|
+
token: ADMIN2,
|
|
5129
5470
|
params: { username: "nobody" },
|
|
5130
5471
|
body: { displayName: "Nobody", username: "nobody", password: "none123" }
|
|
5131
5472
|
},
|
|
@@ -5137,7 +5478,7 @@ var SASjsApi = (() => {
|
|
|
5137
5478
|
description: "refuses a display-name change on a provider-managed account",
|
|
5138
5479
|
identity: PROVIDER_MANAGED,
|
|
5139
5480
|
request: {
|
|
5140
|
-
token:
|
|
5481
|
+
token: ADMIN2,
|
|
5141
5482
|
params: { username: "diruser" },
|
|
5142
5483
|
body: { displayName: "Renamed", username: "diruser", password: "dir123" }
|
|
5143
5484
|
},
|
|
@@ -5152,7 +5493,7 @@ var SASjsApi = (() => {
|
|
|
5152
5493
|
description: "refuses a username another account already has",
|
|
5153
5494
|
identity: ADMIN_SIGNED_IN,
|
|
5154
5495
|
request: {
|
|
5155
|
-
token:
|
|
5496
|
+
token: ADMIN2,
|
|
5156
5497
|
params: { username: "user2" },
|
|
5157
5498
|
body: { username: "admin", displayName: "Demo User", password: "user123" }
|
|
5158
5499
|
},
|
|
@@ -5163,7 +5504,7 @@ var SASjsApi = (() => {
|
|
|
5163
5504
|
route: "DELETE /SASjsApi/user/{uid}",
|
|
5164
5505
|
description: "deletes an account as an administrator, without a password",
|
|
5165
5506
|
identity: ADMIN_SIGNED_IN,
|
|
5166
|
-
request: { token:
|
|
5507
|
+
request: { token: ADMIN2, params: { uid: RESTRICTED_UID }, body: {} },
|
|
5167
5508
|
expect: { status: 200, body: "Account Deleted!" }
|
|
5168
5509
|
},
|
|
5169
5510
|
{
|
|
@@ -5171,7 +5512,7 @@ var SASjsApi = (() => {
|
|
|
5171
5512
|
route: "DELETE /SASjsApi/user/{uid}",
|
|
5172
5513
|
description: "refuses a deletion of somebody else's account",
|
|
5173
5514
|
identity: ADMIN_SIGNED_IN,
|
|
5174
|
-
request: { token:
|
|
5515
|
+
request: { token: RESTRICTED2, params: { uid: ADMIN_UID }, body: {} },
|
|
5175
5516
|
expect: { status: 401, error: "Admin account required" }
|
|
5176
5517
|
},
|
|
5177
5518
|
{
|
|
@@ -5179,7 +5520,7 @@ var SASjsApi = (() => {
|
|
|
5179
5520
|
route: "DELETE /SASjsApi/user/{uid}",
|
|
5180
5521
|
description: "answers 404 for an identifier no account has",
|
|
5181
5522
|
identity: ADMIN_SIGNED_IN,
|
|
5182
|
-
request: { token:
|
|
5523
|
+
request: { token: ADMIN2, params: { uid: "user-none" }, body: {} },
|
|
5183
5524
|
expect: { status: 404, error: "User is not found." }
|
|
5184
5525
|
},
|
|
5185
5526
|
{
|
|
@@ -5188,7 +5529,7 @@ var SASjsApi = (() => {
|
|
|
5188
5529
|
description: "deletes an account looked up by username",
|
|
5189
5530
|
identity: ADMIN_SIGNED_IN,
|
|
5190
5531
|
request: {
|
|
5191
|
-
token:
|
|
5532
|
+
token: ADMIN2,
|
|
5192
5533
|
params: { username: "user2" },
|
|
5193
5534
|
body: {}
|
|
5194
5535
|
},
|
|
@@ -5200,7 +5541,7 @@ var SASjsApi = (() => {
|
|
|
5200
5541
|
description: "refuses a self-deletion whose password is wrong",
|
|
5201
5542
|
identity: ADMIN_SIGNED_IN,
|
|
5202
5543
|
request: {
|
|
5203
|
-
token:
|
|
5544
|
+
token: RESTRICTED2,
|
|
5204
5545
|
params: { username: "user2" },
|
|
5205
5546
|
body: { password: "wrong123" }
|
|
5206
5547
|
},
|
|
@@ -5211,7 +5552,7 @@ var SASjsApi = (() => {
|
|
|
5211
5552
|
route: "DELETE /SASjsApi/user/by/username/{username}",
|
|
5212
5553
|
description: "answers 404 for a username no account has",
|
|
5213
5554
|
identity: ADMIN_SIGNED_IN,
|
|
5214
|
-
request: { token:
|
|
5555
|
+
request: { token: ADMIN2, params: { username: "nobody" }, body: {} },
|
|
5215
5556
|
expect: { status: 404, error: "User is not found." }
|
|
5216
5557
|
},
|
|
5217
5558
|
// ----------------------------------------------------------------- groups
|
|
@@ -5220,7 +5561,7 @@ var SASjsApi = (() => {
|
|
|
5220
5561
|
route: "GET /SASjsApi/group",
|
|
5221
5562
|
description: "lists the groups",
|
|
5222
5563
|
identity: ADMIN_SIGNED_IN,
|
|
5223
|
-
request: { token:
|
|
5564
|
+
request: { token: RESTRICTED2 },
|
|
5224
5565
|
expect: {
|
|
5225
5566
|
status: 200,
|
|
5226
5567
|
body: [
|
|
@@ -5242,7 +5583,7 @@ var SASjsApi = (() => {
|
|
|
5242
5583
|
route: "GET /SASjsApi/group/{uid}",
|
|
5243
5584
|
description: "returns a group and its members",
|
|
5244
5585
|
identity: ADMIN_SIGNED_IN,
|
|
5245
|
-
request: { token:
|
|
5586
|
+
request: { token: RESTRICTED2, params: { uid: "group-admins" } },
|
|
5246
5587
|
expect: {
|
|
5247
5588
|
status: 200,
|
|
5248
5589
|
partial: {
|
|
@@ -5265,7 +5606,7 @@ var SASjsApi = (() => {
|
|
|
5265
5606
|
route: "GET /SASjsApi/group/{uid}",
|
|
5266
5607
|
description: "answers 404 for an identifier no group has",
|
|
5267
5608
|
identity: ADMIN_SIGNED_IN,
|
|
5268
|
-
request: { token:
|
|
5609
|
+
request: { token: ADMIN2, params: { uid: "group-none" } },
|
|
5269
5610
|
expect: { status: 404, error: "Group not found." }
|
|
5270
5611
|
},
|
|
5271
5612
|
{
|
|
@@ -5273,7 +5614,7 @@ var SASjsApi = (() => {
|
|
|
5273
5614
|
route: "GET /SASjsApi/group/by/groupname/{name}",
|
|
5274
5615
|
description: "finds a group by name",
|
|
5275
5616
|
identity: ADMIN_SIGNED_IN,
|
|
5276
|
-
request: { token:
|
|
5617
|
+
request: { token: ADMIN2, params: { name: "DCGroup" } },
|
|
5277
5618
|
expect: {
|
|
5278
5619
|
status: 200,
|
|
5279
5620
|
partial: { uid: "group-data-controller", name: "DCGroup" }
|
|
@@ -5284,7 +5625,7 @@ var SASjsApi = (() => {
|
|
|
5284
5625
|
route: "GET /SASjsApi/group/by/groupname/{name}",
|
|
5285
5626
|
description: "answers 404 for a name no group has",
|
|
5286
5627
|
identity: ADMIN_SIGNED_IN,
|
|
5287
|
-
request: { token:
|
|
5628
|
+
request: { token: ADMIN2, params: { name: "nope" } },
|
|
5288
5629
|
expect: { status: 404, error: "Group not found." }
|
|
5289
5630
|
},
|
|
5290
5631
|
{
|
|
@@ -5293,7 +5634,7 @@ var SASjsApi = (() => {
|
|
|
5293
5634
|
description: "creates a group with no members",
|
|
5294
5635
|
identity: ADMIN_SIGNED_IN,
|
|
5295
5636
|
request: {
|
|
5296
|
-
token:
|
|
5637
|
+
token: ADMIN2,
|
|
5297
5638
|
body: { name: "NewGroup", description: "A new group", isActive: true }
|
|
5298
5639
|
},
|
|
5299
5640
|
expect: {
|
|
@@ -5312,7 +5653,7 @@ var SASjsApi = (() => {
|
|
|
5312
5653
|
description: "refuses a creation by a caller who is not an administrator",
|
|
5313
5654
|
identity: ADMIN_SIGNED_IN,
|
|
5314
5655
|
request: {
|
|
5315
|
-
token:
|
|
5656
|
+
token: RESTRICTED2,
|
|
5316
5657
|
body: { name: "NewGroup", description: "x" }
|
|
5317
5658
|
},
|
|
5318
5659
|
expect: { status: 401, error: "Admin account required" }
|
|
@@ -5322,7 +5663,7 @@ var SASjsApi = (() => {
|
|
|
5322
5663
|
route: "POST /SASjsApi/group",
|
|
5323
5664
|
description: "refuses a name that is taken",
|
|
5324
5665
|
identity: ADMIN_SIGNED_IN,
|
|
5325
|
-
request: { token:
|
|
5666
|
+
request: { token: ADMIN2, body: { name: "DCGroup", description: "again" } },
|
|
5326
5667
|
expect: { status: 409, error: "Group name already exists." }
|
|
5327
5668
|
},
|
|
5328
5669
|
{
|
|
@@ -5331,7 +5672,7 @@ var SASjsApi = (() => {
|
|
|
5331
5672
|
description: "adds a member and returns the group",
|
|
5332
5673
|
identity: ADMIN_SIGNED_IN,
|
|
5333
5674
|
request: {
|
|
5334
|
-
token:
|
|
5675
|
+
token: ADMIN2,
|
|
5335
5676
|
params: { groupUid: "group-admins", userUid: RESTRICTED_UID }
|
|
5336
5677
|
},
|
|
5337
5678
|
expect: {
|
|
@@ -5345,7 +5686,7 @@ var SASjsApi = (() => {
|
|
|
5345
5686
|
description: "refuses a change to the reserved public group",
|
|
5346
5687
|
identity: PROVIDER_MANAGED,
|
|
5347
5688
|
request: {
|
|
5348
|
-
token:
|
|
5689
|
+
token: ADMIN2,
|
|
5349
5690
|
params: { groupUid: "group-public", userUid: RESTRICTED_UID }
|
|
5350
5691
|
},
|
|
5351
5692
|
expect: { status: 400, error: "Can't add/remove user to 'public' group." }
|
|
@@ -5356,7 +5697,7 @@ var SASjsApi = (() => {
|
|
|
5356
5697
|
description: "refuses a membership change by a non-administrator",
|
|
5357
5698
|
identity: ADMIN_SIGNED_IN,
|
|
5358
5699
|
request: {
|
|
5359
|
-
token:
|
|
5700
|
+
token: RESTRICTED2,
|
|
5360
5701
|
params: { groupUid: "group-admins", userUid: RESTRICTED_UID }
|
|
5361
5702
|
},
|
|
5362
5703
|
expect: { status: 401, error: "Admin account required" }
|
|
@@ -5367,7 +5708,7 @@ var SASjsApi = (() => {
|
|
|
5367
5708
|
description: "answers 404 for a group that does not exist",
|
|
5368
5709
|
identity: ADMIN_SIGNED_IN,
|
|
5369
5710
|
request: {
|
|
5370
|
-
token:
|
|
5711
|
+
token: ADMIN2,
|
|
5371
5712
|
params: { groupUid: "group-none", userUid: RESTRICTED_UID }
|
|
5372
5713
|
},
|
|
5373
5714
|
expect: { status: 404, error: "Group not found." }
|
|
@@ -5378,7 +5719,7 @@ var SASjsApi = (() => {
|
|
|
5378
5719
|
description: "refuses a membership change on a provider-managed group",
|
|
5379
5720
|
identity: PROVIDER_MANAGED,
|
|
5380
5721
|
request: {
|
|
5381
|
-
token:
|
|
5722
|
+
token: ADMIN2,
|
|
5382
5723
|
params: { groupUid: "group-directory", userUid: RESTRICTED_UID }
|
|
5383
5724
|
},
|
|
5384
5725
|
expect: {
|
|
@@ -5392,7 +5733,7 @@ var SASjsApi = (() => {
|
|
|
5392
5733
|
description: "removes a member and returns the group",
|
|
5393
5734
|
identity: ADMIN_SIGNED_IN,
|
|
5394
5735
|
request: {
|
|
5395
|
-
token:
|
|
5736
|
+
token: ADMIN2,
|
|
5396
5737
|
params: { groupUid: "group-data-controller", userUid: RESTRICTED_UID }
|
|
5397
5738
|
},
|
|
5398
5739
|
expect: {
|
|
@@ -5406,7 +5747,7 @@ var SASjsApi = (() => {
|
|
|
5406
5747
|
description: "refuses a membership change for a provider-managed user",
|
|
5407
5748
|
identity: PROVIDER_MANAGED,
|
|
5408
5749
|
request: {
|
|
5409
|
-
token:
|
|
5750
|
+
token: ADMIN2,
|
|
5410
5751
|
params: { groupUid: "group-admins", userUid: "user-directory" }
|
|
5411
5752
|
},
|
|
5412
5753
|
expect: {
|
|
@@ -5420,7 +5761,7 @@ var SASjsApi = (() => {
|
|
|
5420
5761
|
description: "refuses a membership change for a provider-managed user",
|
|
5421
5762
|
identity: PROVIDER_MANAGED,
|
|
5422
5763
|
request: {
|
|
5423
|
-
token:
|
|
5764
|
+
token: ADMIN2,
|
|
5424
5765
|
params: { groupUid: "group-admins", userUid: "user-directory" }
|
|
5425
5766
|
},
|
|
5426
5767
|
expect: {
|
|
@@ -5434,7 +5775,7 @@ var SASjsApi = (() => {
|
|
|
5434
5775
|
description: "refuses a change to the reserved public group",
|
|
5435
5776
|
identity: PROVIDER_MANAGED,
|
|
5436
5777
|
request: {
|
|
5437
|
-
token:
|
|
5778
|
+
token: ADMIN2,
|
|
5438
5779
|
params: { groupUid: "group-public", userUid: RESTRICTED_UID }
|
|
5439
5780
|
},
|
|
5440
5781
|
expect: { status: 400, error: "Can't add/remove user to 'public' group." }
|
|
@@ -5445,7 +5786,7 @@ var SASjsApi = (() => {
|
|
|
5445
5786
|
description: "refuses a membership change by a non-administrator",
|
|
5446
5787
|
identity: ADMIN_SIGNED_IN,
|
|
5447
5788
|
request: {
|
|
5448
|
-
token:
|
|
5789
|
+
token: RESTRICTED2,
|
|
5449
5790
|
params: { groupUid: "group-data-controller", userUid: RESTRICTED_UID }
|
|
5450
5791
|
},
|
|
5451
5792
|
expect: { status: 401, error: "Admin account required" }
|
|
@@ -5456,7 +5797,7 @@ var SASjsApi = (() => {
|
|
|
5456
5797
|
description: "answers 404 for a member that does not exist",
|
|
5457
5798
|
identity: ADMIN_SIGNED_IN,
|
|
5458
5799
|
request: {
|
|
5459
|
-
token:
|
|
5800
|
+
token: ADMIN2,
|
|
5460
5801
|
params: { groupUid: "group-admins", userUid: "user-none" }
|
|
5461
5802
|
},
|
|
5462
5803
|
expect: { status: 404, error: "User not found." }
|
|
@@ -5467,7 +5808,7 @@ var SASjsApi = (() => {
|
|
|
5467
5808
|
description: "refuses a membership change on a provider-managed group",
|
|
5468
5809
|
identity: PROVIDER_MANAGED,
|
|
5469
5810
|
request: {
|
|
5470
|
-
token:
|
|
5811
|
+
token: ADMIN2,
|
|
5471
5812
|
params: { groupUid: "group-directory", userUid: RESTRICTED_UID }
|
|
5472
5813
|
},
|
|
5473
5814
|
expect: {
|
|
@@ -5480,7 +5821,7 @@ var SASjsApi = (() => {
|
|
|
5480
5821
|
route: "DELETE /SASjsApi/group/{uid}",
|
|
5481
5822
|
description: "deletes a group",
|
|
5482
5823
|
identity: ADMIN_SIGNED_IN,
|
|
5483
|
-
request: { token:
|
|
5824
|
+
request: { token: ADMIN2, params: { uid: "group-data-controller" } },
|
|
5484
5825
|
expect: { status: 200 }
|
|
5485
5826
|
},
|
|
5486
5827
|
{
|
|
@@ -5488,7 +5829,7 @@ var SASjsApi = (() => {
|
|
|
5488
5829
|
route: "DELETE /SASjsApi/group/{uid}",
|
|
5489
5830
|
description: "refuses a deletion by a caller who is not an administrator",
|
|
5490
5831
|
identity: ADMIN_SIGNED_IN,
|
|
5491
|
-
request: { token:
|
|
5832
|
+
request: { token: RESTRICTED2, params: { uid: "group-admins" } },
|
|
5492
5833
|
expect: { status: 401, error: "Admin account required" }
|
|
5493
5834
|
},
|
|
5494
5835
|
{
|
|
@@ -5496,7 +5837,7 @@ var SASjsApi = (() => {
|
|
|
5496
5837
|
route: "DELETE /SASjsApi/group/{uid}",
|
|
5497
5838
|
description: "answers 404 for an identifier no group has",
|
|
5498
5839
|
identity: ADMIN_SIGNED_IN,
|
|
5499
|
-
request: { token:
|
|
5840
|
+
request: { token: ADMIN2, params: { uid: "group-none" } },
|
|
5500
5841
|
expect: { status: 404, error: "Group not found." }
|
|
5501
5842
|
},
|
|
5502
5843
|
// ------------------------------------------------------------ permissions
|
|
@@ -5505,7 +5846,7 @@ var SASjsApi = (() => {
|
|
|
5505
5846
|
route: "GET /SASjsApi/info/authorizedRoutes",
|
|
5506
5847
|
description: "answers the routes that accept a rule, to any caller",
|
|
5507
5848
|
identity: ADMIN_SIGNED_IN,
|
|
5508
|
-
request: { token:
|
|
5849
|
+
request: { token: RESTRICTED2 },
|
|
5509
5850
|
expect: {
|
|
5510
5851
|
status: 200,
|
|
5511
5852
|
body: {
|
|
@@ -5529,7 +5870,7 @@ var SASjsApi = (() => {
|
|
|
5529
5870
|
route: "GET /SASjsApi/info/myAuthorizedRoutes",
|
|
5530
5871
|
description: "answers every route to an administrator",
|
|
5531
5872
|
identity: ADMIN_SIGNED_IN,
|
|
5532
|
-
request: { token:
|
|
5873
|
+
request: { token: ADMIN2 },
|
|
5533
5874
|
expect: {
|
|
5534
5875
|
status: 200,
|
|
5535
5876
|
body: {
|
|
@@ -5553,7 +5894,7 @@ var SASjsApi = (() => {
|
|
|
5553
5894
|
route: "GET /SASjsApi/info/myAuthorizedRoutes",
|
|
5554
5895
|
description: "answers a caller only the routes its rules grant",
|
|
5555
5896
|
identity: ADMIN_SIGNED_IN,
|
|
5556
|
-
request: { token:
|
|
5897
|
+
request: { token: RESTRICTED2 },
|
|
5557
5898
|
expect: {
|
|
5558
5899
|
status: 200,
|
|
5559
5900
|
// /AppStream is visible whatever the rules say; the two grants come from
|
|
@@ -5569,7 +5910,7 @@ var SASjsApi = (() => {
|
|
|
5569
5910
|
route: "GET /SASjsApi/permission",
|
|
5570
5911
|
description: "returns every rule to an administrator",
|
|
5571
5912
|
identity: ADMIN_SIGNED_IN,
|
|
5572
|
-
request: { token:
|
|
5913
|
+
request: { token: ADMIN2 },
|
|
5573
5914
|
expect: {
|
|
5574
5915
|
status: 200,
|
|
5575
5916
|
body: [
|
|
@@ -5602,7 +5943,7 @@ var SASjsApi = (() => {
|
|
|
5602
5943
|
route: "GET /SASjsApi/permission",
|
|
5603
5944
|
description: "returns a caller only their own rules and their groups'",
|
|
5604
5945
|
identity: ADMIN_SIGNED_IN,
|
|
5605
|
-
request: { token:
|
|
5946
|
+
request: { token: RESTRICTED2 },
|
|
5606
5947
|
expect: {
|
|
5607
5948
|
status: 200,
|
|
5608
5949
|
body: [
|
|
@@ -5644,7 +5985,7 @@ var SASjsApi = (() => {
|
|
|
5644
5985
|
description: "creates a rule for a user",
|
|
5645
5986
|
identity: ADMIN_SIGNED_IN,
|
|
5646
5987
|
request: {
|
|
5647
|
-
token:
|
|
5988
|
+
token: ADMIN2,
|
|
5648
5989
|
body: {
|
|
5649
5990
|
path: "/SASjsApi/drive/folder",
|
|
5650
5991
|
type: "Route",
|
|
@@ -5664,7 +6005,7 @@ var SASjsApi = (() => {
|
|
|
5664
6005
|
description: "creates a rule for a group",
|
|
5665
6006
|
identity: ADMIN_SIGNED_IN,
|
|
5666
6007
|
request: {
|
|
5667
|
-
token:
|
|
6008
|
+
token: ADMIN2,
|
|
5668
6009
|
body: {
|
|
5669
6010
|
path: "/SASjsApi/drive/rename",
|
|
5670
6011
|
type: "Route",
|
|
@@ -5688,7 +6029,7 @@ var SASjsApi = (() => {
|
|
|
5688
6029
|
description: "refuses a principal type that is neither a user nor a group",
|
|
5689
6030
|
identity: ADMIN_SIGNED_IN,
|
|
5690
6031
|
request: {
|
|
5691
|
-
token:
|
|
6032
|
+
token: ADMIN2,
|
|
5692
6033
|
body: {
|
|
5693
6034
|
path: "/SASjsApi/drive/deploy",
|
|
5694
6035
|
type: "Route",
|
|
@@ -5708,7 +6049,7 @@ var SASjsApi = (() => {
|
|
|
5708
6049
|
description: "refuses a rule assigned to an administrator",
|
|
5709
6050
|
identity: ADMIN_SIGNED_IN,
|
|
5710
6051
|
request: {
|
|
5711
|
-
token:
|
|
6052
|
+
token: ADMIN2,
|
|
5712
6053
|
body: {
|
|
5713
6054
|
path: "/SASjsApi/drive/folder",
|
|
5714
6055
|
type: "Route",
|
|
@@ -5728,7 +6069,7 @@ var SASjsApi = (() => {
|
|
|
5728
6069
|
description: "refuses a creation by a non-administrator",
|
|
5729
6070
|
identity: ADMIN_SIGNED_IN,
|
|
5730
6071
|
request: {
|
|
5731
|
-
token:
|
|
6072
|
+
token: RESTRICTED2,
|
|
5732
6073
|
body: {
|
|
5733
6074
|
path: "/SASjsApi/drive/folder",
|
|
5734
6075
|
type: "Route",
|
|
@@ -5745,7 +6086,7 @@ var SASjsApi = (() => {
|
|
|
5745
6086
|
description: "answers 404 for a principal that does not exist",
|
|
5746
6087
|
identity: ADMIN_SIGNED_IN,
|
|
5747
6088
|
request: {
|
|
5748
|
-
token:
|
|
6089
|
+
token: ADMIN2,
|
|
5749
6090
|
body: {
|
|
5750
6091
|
path: "/SASjsApi/drive/rename",
|
|
5751
6092
|
type: "Route",
|
|
@@ -5762,7 +6103,7 @@ var SASjsApi = (() => {
|
|
|
5762
6103
|
description: "refuses a group rule that already exists",
|
|
5763
6104
|
identity: ADMIN_SIGNED_IN,
|
|
5764
6105
|
request: {
|
|
5765
|
-
token:
|
|
6106
|
+
token: ADMIN2,
|
|
5766
6107
|
body: {
|
|
5767
6108
|
path: "/SASjsApi/drive/file",
|
|
5768
6109
|
type: "Route",
|
|
@@ -5782,7 +6123,7 @@ var SASjsApi = (() => {
|
|
|
5782
6123
|
description: "refuses a rule that already exists",
|
|
5783
6124
|
identity: ADMIN_SIGNED_IN,
|
|
5784
6125
|
request: {
|
|
5785
|
-
token:
|
|
6126
|
+
token: ADMIN2,
|
|
5786
6127
|
body: {
|
|
5787
6128
|
path: "/SASjsApi/code/execute",
|
|
5788
6129
|
type: "Route",
|
|
@@ -5802,7 +6143,7 @@ var SASjsApi = (() => {
|
|
|
5802
6143
|
description: "flips a rule from Deny to Grant",
|
|
5803
6144
|
identity: ADMIN_SIGNED_IN,
|
|
5804
6145
|
request: {
|
|
5805
|
-
token:
|
|
6146
|
+
token: ADMIN2,
|
|
5806
6147
|
params: { uid: "rule-code" },
|
|
5807
6148
|
body: { setting: "Grant" }
|
|
5808
6149
|
},
|
|
@@ -5814,7 +6155,7 @@ var SASjsApi = (() => {
|
|
|
5814
6155
|
description: "refuses a change by a non-administrator",
|
|
5815
6156
|
identity: ADMIN_SIGNED_IN,
|
|
5816
6157
|
request: {
|
|
5817
|
-
token:
|
|
6158
|
+
token: RESTRICTED2,
|
|
5818
6159
|
params: { uid: "rule-code" },
|
|
5819
6160
|
body: { setting: "Grant" }
|
|
5820
6161
|
},
|
|
@@ -5826,7 +6167,7 @@ var SASjsApi = (() => {
|
|
|
5826
6167
|
description: "answers 404 for a rule that does not exist",
|
|
5827
6168
|
identity: ADMIN_SIGNED_IN,
|
|
5828
6169
|
request: {
|
|
5829
|
-
token:
|
|
6170
|
+
token: ADMIN2,
|
|
5830
6171
|
params: { uid: "rule-none" },
|
|
5831
6172
|
body: { setting: "Grant" }
|
|
5832
6173
|
},
|
|
@@ -5837,7 +6178,7 @@ var SASjsApi = (() => {
|
|
|
5837
6178
|
route: "DELETE /SASjsApi/permission/{uid}",
|
|
5838
6179
|
description: "deletes a rule",
|
|
5839
6180
|
identity: ADMIN_SIGNED_IN,
|
|
5840
|
-
request: { token:
|
|
6181
|
+
request: { token: ADMIN2, params: { uid: "rule-code" } },
|
|
5841
6182
|
expect: { status: 200, body: "Permission Deleted!" }
|
|
5842
6183
|
},
|
|
5843
6184
|
{
|
|
@@ -5845,7 +6186,7 @@ var SASjsApi = (() => {
|
|
|
5845
6186
|
route: "DELETE /SASjsApi/permission/{uid}",
|
|
5846
6187
|
description: "refuses a deletion by a non-administrator",
|
|
5847
6188
|
identity: ADMIN_SIGNED_IN,
|
|
5848
|
-
request: { token:
|
|
6189
|
+
request: { token: RESTRICTED2, params: { uid: "rule-code" } },
|
|
5849
6190
|
expect: { status: 401, error: "Admin account required" }
|
|
5850
6191
|
},
|
|
5851
6192
|
{
|
|
@@ -5853,7 +6194,7 @@ var SASjsApi = (() => {
|
|
|
5853
6194
|
route: "DELETE /SASjsApi/permission/{uid}",
|
|
5854
6195
|
description: "answers 404 for a rule that does not exist",
|
|
5855
6196
|
identity: ADMIN_SIGNED_IN,
|
|
5856
|
-
request: { token:
|
|
6197
|
+
request: { token: ADMIN2, params: { uid: "rule-none" } },
|
|
5857
6198
|
expect: { status: 404, error: "Permission not found." }
|
|
5858
6199
|
},
|
|
5859
6200
|
// --------------------------------------------------------------- clients
|
|
@@ -5862,7 +6203,7 @@ var SASjsApi = (() => {
|
|
|
5862
6203
|
route: "GET /SASjsApi/client",
|
|
5863
6204
|
description: "lists the registered clients",
|
|
5864
6205
|
identity: ADMIN_SIGNED_IN,
|
|
5865
|
-
request: { token:
|
|
6206
|
+
request: { token: ADMIN2 },
|
|
5866
6207
|
expect: {
|
|
5867
6208
|
status: 200,
|
|
5868
6209
|
body: [
|
|
@@ -5886,7 +6227,7 @@ var SASjsApi = (() => {
|
|
|
5886
6227
|
route: "GET /SASjsApi/client",
|
|
5887
6228
|
description: "refuses the list to a caller who is not an administrator",
|
|
5888
6229
|
identity: ADMIN_SIGNED_IN,
|
|
5889
|
-
request: { token:
|
|
6230
|
+
request: { token: RESTRICTED2 },
|
|
5890
6231
|
expect: { status: 401, error: "Admin account required" }
|
|
5891
6232
|
},
|
|
5892
6233
|
{
|
|
@@ -5895,7 +6236,7 @@ var SASjsApi = (() => {
|
|
|
5895
6236
|
description: "registers a client",
|
|
5896
6237
|
identity: ADMIN_SIGNED_IN,
|
|
5897
6238
|
request: {
|
|
5898
|
-
token:
|
|
6239
|
+
token: ADMIN2,
|
|
5899
6240
|
body: {
|
|
5900
6241
|
clientId: "new_app",
|
|
5901
6242
|
clientSecret: "new_secret",
|
|
@@ -5919,7 +6260,7 @@ var SASjsApi = (() => {
|
|
|
5919
6260
|
description: "applies the schema defaults when the lifetimes are omitted",
|
|
5920
6261
|
identity: ADMIN_SIGNED_IN,
|
|
5921
6262
|
request: {
|
|
5922
|
-
token:
|
|
6263
|
+
token: ADMIN2,
|
|
5923
6264
|
body: { clientId: "default_app", clientSecret: "default_secret" }
|
|
5924
6265
|
},
|
|
5925
6266
|
expect: {
|
|
@@ -5938,7 +6279,7 @@ var SASjsApi = (() => {
|
|
|
5938
6279
|
description: "refuses a registration by a non-administrator",
|
|
5939
6280
|
identity: ADMIN_SIGNED_IN,
|
|
5940
6281
|
request: {
|
|
5941
|
-
token:
|
|
6282
|
+
token: RESTRICTED2,
|
|
5942
6283
|
body: {
|
|
5943
6284
|
clientId: "new_app",
|
|
5944
6285
|
clientSecret: "new_secret",
|
|
@@ -5954,7 +6295,7 @@ var SASjsApi = (() => {
|
|
|
5954
6295
|
description: "refuses a client id that is registered, with the 403 the server sends",
|
|
5955
6296
|
identity: ADMIN_SIGNED_IN,
|
|
5956
6297
|
request: {
|
|
5957
|
-
token:
|
|
6298
|
+
token: ADMIN2,
|
|
5958
6299
|
body: {
|
|
5959
6300
|
clientId: "web_app",
|
|
5960
6301
|
clientSecret: "other",
|
|
@@ -5971,7 +6312,7 @@ var SASjsApi = (() => {
|
|
|
5971
6312
|
description: "changes the caller’s own password",
|
|
5972
6313
|
identity: ADMIN_SIGNED_IN,
|
|
5973
6314
|
request: {
|
|
5974
|
-
token:
|
|
6315
|
+
token: RESTRICTED2,
|
|
5975
6316
|
body: { currentPassword: "user123", newPassword: "changed123" }
|
|
5976
6317
|
},
|
|
5977
6318
|
expect: { status: 204 }
|
|
@@ -5981,7 +6322,7 @@ var SASjsApi = (() => {
|
|
|
5981
6322
|
route: "PATCH /SASjsApi/auth/updatePassword",
|
|
5982
6323
|
description: "refuses a body without the current password",
|
|
5983
6324
|
identity: ADMIN_SIGNED_IN,
|
|
5984
|
-
request: { token:
|
|
6325
|
+
request: { token: RESTRICTED2, body: { newPassword: "changed123" } },
|
|
5985
6326
|
expect: { status: 400, error: '"currentPassword" is required' }
|
|
5986
6327
|
},
|
|
5987
6328
|
{
|
|
@@ -6000,7 +6341,7 @@ var SASjsApi = (() => {
|
|
|
6000
6341
|
description: "refuses a change whose current password is wrong",
|
|
6001
6342
|
identity: ADMIN_SIGNED_IN,
|
|
6002
6343
|
request: {
|
|
6003
|
-
token:
|
|
6344
|
+
token: RESTRICTED2,
|
|
6004
6345
|
body: { currentPassword: "wrong", newPassword: "changed123" }
|
|
6005
6346
|
},
|
|
6006
6347
|
expect: { status: 403, error: "Invalid current password!" }
|
|
@@ -6021,6 +6362,112 @@ var SASjsApi = (() => {
|
|
|
6021
6362
|
}
|
|
6022
6363
|
];
|
|
6023
6364
|
|
|
6365
|
+
// src/session/service.ts
|
|
6366
|
+
var createSessionService = (store, host) => {
|
|
6367
|
+
const notFound2 = (id) => `Session with ID '${id}' was not found.`;
|
|
6368
|
+
const visible = async (caller, id) => {
|
|
6369
|
+
if (!caller) throw new ApiError(401, "Unauthorized");
|
|
6370
|
+
const reader = await store.userById(
|
|
6371
|
+
caller.userId
|
|
6372
|
+
);
|
|
6373
|
+
if (!reader || !reader.isActive) throw new ApiError(401, "Unauthorized");
|
|
6374
|
+
const session = await host.session(id);
|
|
6375
|
+
if (!session) throw new ApiError(404, notFound2(id));
|
|
6376
|
+
const owner = session.owner;
|
|
6377
|
+
if (owner !== reader.uid && owner !== reader.username && !reader.isAdmin)
|
|
6378
|
+
throw new ApiError(404, notFound2(id));
|
|
6379
|
+
return session;
|
|
6380
|
+
};
|
|
6381
|
+
return {
|
|
6382
|
+
async summary(caller, id) {
|
|
6383
|
+
const session = await visible(caller, id);
|
|
6384
|
+
return session.summary;
|
|
6385
|
+
},
|
|
6386
|
+
async state(caller, id) {
|
|
6387
|
+
await visible(caller, id);
|
|
6388
|
+
const state = await host.state(id);
|
|
6389
|
+
if (!state) throw new ApiError(404, notFound2(id));
|
|
6390
|
+
return state;
|
|
6391
|
+
},
|
|
6392
|
+
async log(caller, id) {
|
|
6393
|
+
await visible(caller, id);
|
|
6394
|
+
const log = await host.log(id);
|
|
6395
|
+
if (log === void 0) throw new ApiError(404, notFound2(id));
|
|
6396
|
+
return log;
|
|
6397
|
+
},
|
|
6398
|
+
async output(caller, id) {
|
|
6399
|
+
await visible(caller, id);
|
|
6400
|
+
const output = await host.output(id);
|
|
6401
|
+
if (output === void 0) throw new ApiError(404, notFound2(id));
|
|
6402
|
+
return output;
|
|
6403
|
+
}
|
|
6404
|
+
};
|
|
6405
|
+
};
|
|
6406
|
+
|
|
6407
|
+
// src/session/memory-host.ts
|
|
6408
|
+
var DEFAULT_SESSIONS = {
|
|
6409
|
+
"sess-admin": {
|
|
6410
|
+
owner: "user-admin",
|
|
6411
|
+
summary: {
|
|
6412
|
+
sessionId: "sess-admin",
|
|
6413
|
+
state: "completed",
|
|
6414
|
+
pid: 4242,
|
|
6415
|
+
creationTimeStamp: "2026-11-07T09:00:00.000Z",
|
|
6416
|
+
deathTimeStamp: "2026-11-07T09:00:04.000Z",
|
|
6417
|
+
expiresAfterMins: 60
|
|
6418
|
+
}
|
|
6419
|
+
},
|
|
6420
|
+
"sess-restricted": {
|
|
6421
|
+
owner: "user-restricted",
|
|
6422
|
+
summary: {
|
|
6423
|
+
sessionId: "sess-restricted",
|
|
6424
|
+
state: "running",
|
|
6425
|
+
pid: 4243,
|
|
6426
|
+
creationTimeStamp: "2026-11-07T09:05:00.000Z"
|
|
6427
|
+
}
|
|
6428
|
+
},
|
|
6429
|
+
"sess-silent": {
|
|
6430
|
+
owner: "user-admin",
|
|
6431
|
+
summary: {
|
|
6432
|
+
sessionId: "sess-silent",
|
|
6433
|
+
state: "running",
|
|
6434
|
+
pid: 4244,
|
|
6435
|
+
creationTimeStamp: "2026-11-07T09:10:00.000Z"
|
|
6436
|
+
}
|
|
6437
|
+
}
|
|
6438
|
+
};
|
|
6439
|
+
var STATES = {
|
|
6440
|
+
"sess-admin": { state: "completed", pid: 4242, lineCount: 12 },
|
|
6441
|
+
"sess-restricted": { state: "running", pid: 4243, lineCount: 3 }
|
|
6442
|
+
};
|
|
6443
|
+
var LOGS = {
|
|
6444
|
+
"sess-admin": "NOTE: session started\nNOTE: session completed\n",
|
|
6445
|
+
"sess-restricted": "NOTE: session started\n",
|
|
6446
|
+
"sess-silent": ""
|
|
6447
|
+
};
|
|
6448
|
+
var OUTPUTS = {
|
|
6449
|
+
"sess-admin": "<html><body>42</body></html>",
|
|
6450
|
+
"sess-restricted": "",
|
|
6451
|
+
"sess-silent": ""
|
|
6452
|
+
};
|
|
6453
|
+
var MemorySessionHost = class {
|
|
6454
|
+
constructor(sessions = DEFAULT_SESSIONS) {
|
|
6455
|
+
this.sessions = sessions;
|
|
6456
|
+
}
|
|
6457
|
+
async session(id) {
|
|
6458
|
+
return this.sessions[id];
|
|
6459
|
+
}
|
|
6460
|
+
async state(id) {
|
|
6461
|
+
return STATES[id];
|
|
6462
|
+
}
|
|
6463
|
+
async log(id) {
|
|
6464
|
+
return LOGS[id];
|
|
6465
|
+
}
|
|
6466
|
+
async output(id) {
|
|
6467
|
+
return OUTPUTS[id];
|
|
6468
|
+
}
|
|
6469
|
+
};
|
|
6470
|
+
|
|
6024
6471
|
// src/corpus/runner.ts
|
|
6025
6472
|
var servicesFor = (testCase) => {
|
|
6026
6473
|
const identity = new MemoryIdentityStore(
|
|
@@ -6031,7 +6478,9 @@ var SASjsApi = (() => {
|
|
|
6031
6478
|
testCase.unwritable ? new RefusingDriveStore(testCase.seed || {}) : new MemoryDriveStore(testCase.seed || {})
|
|
6032
6479
|
),
|
|
6033
6480
|
identity: createIdentityService(identity),
|
|
6034
|
-
records: createRecordService(identity)
|
|
6481
|
+
records: createRecordService(identity),
|
|
6482
|
+
registry: new MemoryAppStreamRegistry(),
|
|
6483
|
+
session: createSessionService(identity, new MemorySessionHost())
|
|
6035
6484
|
};
|
|
6036
6485
|
};
|
|
6037
6486
|
var RefusingDriveStore = class extends MemoryDriveStore {
|