@sasjs/api 0.6.1 → 0.7.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/README.md +3 -2
- package/build/browser.js +2218 -118
- package/build/cjs/corpus/records.js +1222 -0
- package/build/cjs/corpus/runner.js +15 -6
- package/build/cjs/host/dispatch.js +190 -2
- package/build/cjs/identity/memory-store.js +196 -11
- package/build/cjs/identity/records.js +398 -0
- package/build/cjs/index.js +8 -1
- package/build/cjs/routes/generated.js +184 -4
- package/build/cjs/routes/overlay.js +53 -58
- package/build/esm/corpus/records.d.ts +25 -0
- package/build/esm/corpus/records.d.ts.map +1 -0
- package/build/esm/corpus/records.js +1219 -0
- package/build/esm/corpus/runner.d.ts.map +1 -1
- package/build/esm/corpus/runner.js +15 -6
- package/build/esm/host/dispatch.d.ts +9 -0
- package/build/esm/host/dispatch.d.ts.map +1 -1
- package/build/esm/host/dispatch.js +190 -2
- package/build/esm/identity/fixture.d.ts +6 -0
- package/build/esm/identity/fixture.d.ts.map +1 -1
- package/build/esm/identity/memory-store.d.ts +29 -5
- package/build/esm/identity/memory-store.d.ts.map +1 -1
- package/build/esm/identity/memory-store.js +196 -11
- package/build/esm/identity/records.d.ts +102 -0
- package/build/esm/identity/records.d.ts.map +1 -0
- package/build/esm/identity/records.js +393 -0
- package/build/esm/identity/types.d.ts +102 -2
- package/build/esm/identity/types.d.ts.map +1 -1
- package/build/esm/index.d.ts +4 -1
- 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 +184 -4
- package/build/esm/routes/overlay.d.ts.map +1 -1
- package/build/esm/routes/overlay.js +53 -58
- package/package.json +1 -1
|
@@ -145,7 +145,7 @@ exports.GENERATED_ROUTES = [
|
|
|
145
145
|
},
|
|
146
146
|
{
|
|
147
147
|
status: 401,
|
|
148
|
-
description: 'The authorization code is invalid, expired, already used, or was issued for another client, or the client id is unknown'
|
|
148
|
+
description: 'The authorization code is invalid, expired, already used, or was issued for another client, or the client id is unknown. This route is unauthenticated, so an unknown client id is a `401` here where `POST /SASLogon/authorize` (which requires a session) answers `403`'
|
|
149
149
|
}
|
|
150
150
|
]
|
|
151
151
|
},
|
|
@@ -239,6 +239,10 @@ exports.GENERATED_ROUTES = [
|
|
|
239
239
|
{
|
|
240
240
|
status: 200,
|
|
241
241
|
description: 'Ok'
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
status: 401,
|
|
245
|
+
description: 'Admin account required'
|
|
242
246
|
}
|
|
243
247
|
]
|
|
244
248
|
},
|
|
@@ -279,6 +283,14 @@ exports.GENERATED_ROUTES = [
|
|
|
279
283
|
{
|
|
280
284
|
status: 200,
|
|
281
285
|
description: 'Ok'
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
status: 401,
|
|
289
|
+
description: 'Admin account required'
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
status: 403,
|
|
293
|
+
description: 'Client ID already exists.'
|
|
282
294
|
}
|
|
283
295
|
]
|
|
284
296
|
},
|
|
@@ -768,7 +780,7 @@ exports.GENERATED_ROUTES = [
|
|
|
768
780
|
},
|
|
769
781
|
{
|
|
770
782
|
status: 409,
|
|
771
|
-
description: 'Folder already exists'
|
|
783
|
+
description: 'Folder already exists. The body is that message as plain text.'
|
|
772
784
|
}
|
|
773
785
|
]
|
|
774
786
|
},
|
|
@@ -808,7 +820,7 @@ exports.GENERATED_ROUTES = [
|
|
|
808
820
|
},
|
|
809
821
|
{
|
|
810
822
|
status: 409,
|
|
811
|
-
description: 'Something already exists at the new path'
|
|
823
|
+
description: 'Something already exists at the new path. The body is that message as plain text.'
|
|
812
824
|
}
|
|
813
825
|
]
|
|
814
826
|
},
|
|
@@ -858,6 +870,14 @@ exports.GENERATED_ROUTES = [
|
|
|
858
870
|
{
|
|
859
871
|
status: 200,
|
|
860
872
|
description: 'Ok'
|
|
873
|
+
},
|
|
874
|
+
{
|
|
875
|
+
status: 401,
|
|
876
|
+
description: 'Admin account required'
|
|
877
|
+
},
|
|
878
|
+
{
|
|
879
|
+
status: 409,
|
|
880
|
+
description: 'Group name already exists.'
|
|
861
881
|
}
|
|
862
882
|
]
|
|
863
883
|
},
|
|
@@ -886,6 +906,22 @@ exports.GENERATED_ROUTES = [
|
|
|
886
906
|
{
|
|
887
907
|
status: 200,
|
|
888
908
|
description: 'Ok'
|
|
909
|
+
},
|
|
910
|
+
{
|
|
911
|
+
status: 400,
|
|
912
|
+
description: "Can't add/remove user to 'public' group."
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
status: 401,
|
|
916
|
+
description: 'Admin account required'
|
|
917
|
+
},
|
|
918
|
+
{
|
|
919
|
+
status: 404,
|
|
920
|
+
description: 'Group not found. / User not found.'
|
|
921
|
+
},
|
|
922
|
+
{
|
|
923
|
+
status: 405,
|
|
924
|
+
description: "Can't add/remove user to group created by external auth provider."
|
|
889
925
|
}
|
|
890
926
|
]
|
|
891
927
|
},
|
|
@@ -914,6 +950,22 @@ exports.GENERATED_ROUTES = [
|
|
|
914
950
|
{
|
|
915
951
|
status: 200,
|
|
916
952
|
description: 'Ok'
|
|
953
|
+
},
|
|
954
|
+
{
|
|
955
|
+
status: 400,
|
|
956
|
+
description: "Can't add/remove user to 'public' group."
|
|
957
|
+
},
|
|
958
|
+
{
|
|
959
|
+
status: 401,
|
|
960
|
+
description: 'Admin account required'
|
|
961
|
+
},
|
|
962
|
+
{
|
|
963
|
+
status: 404,
|
|
964
|
+
description: 'Group not found. / User not found.'
|
|
965
|
+
},
|
|
966
|
+
{
|
|
967
|
+
status: 405,
|
|
968
|
+
description: "Can't add/remove user to group created by external auth provider."
|
|
917
969
|
}
|
|
918
970
|
]
|
|
919
971
|
},
|
|
@@ -936,6 +988,14 @@ exports.GENERATED_ROUTES = [
|
|
|
936
988
|
{
|
|
937
989
|
status: 200,
|
|
938
990
|
description: 'Ok'
|
|
991
|
+
},
|
|
992
|
+
{
|
|
993
|
+
status: 401,
|
|
994
|
+
description: 'Admin account required'
|
|
995
|
+
},
|
|
996
|
+
{
|
|
997
|
+
status: 404,
|
|
998
|
+
description: 'Group not found.'
|
|
939
999
|
}
|
|
940
1000
|
]
|
|
941
1001
|
},
|
|
@@ -958,6 +1018,10 @@ exports.GENERATED_ROUTES = [
|
|
|
958
1018
|
{
|
|
959
1019
|
status: 200,
|
|
960
1020
|
description: 'Ok'
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
status: 404,
|
|
1024
|
+
description: 'Group not found.'
|
|
961
1025
|
}
|
|
962
1026
|
]
|
|
963
1027
|
},
|
|
@@ -980,6 +1044,10 @@ exports.GENERATED_ROUTES = [
|
|
|
980
1044
|
{
|
|
981
1045
|
status: 200,
|
|
982
1046
|
description: 'Ok'
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
status: 404,
|
|
1050
|
+
description: 'Group not found.'
|
|
983
1051
|
}
|
|
984
1052
|
]
|
|
985
1053
|
},
|
|
@@ -1040,6 +1108,14 @@ exports.GENERATED_ROUTES = [
|
|
|
1040
1108
|
{
|
|
1041
1109
|
status: 200,
|
|
1042
1110
|
description: 'Ok'
|
|
1111
|
+
},
|
|
1112
|
+
{
|
|
1113
|
+
status: 401,
|
|
1114
|
+
description: 'Admin account required, or no grant on the route'
|
|
1115
|
+
},
|
|
1116
|
+
{
|
|
1117
|
+
status: 404,
|
|
1118
|
+
description: 'User not found.'
|
|
1043
1119
|
}
|
|
1044
1120
|
]
|
|
1045
1121
|
},
|
|
@@ -1086,6 +1162,22 @@ exports.GENERATED_ROUTES = [
|
|
|
1086
1162
|
{
|
|
1087
1163
|
status: 200,
|
|
1088
1164
|
description: 'Ok'
|
|
1165
|
+
},
|
|
1166
|
+
{
|
|
1167
|
+
status: 400,
|
|
1168
|
+
description: 'Can not add permission for admin user. / Invalid principal type. Valid types are user or group.'
|
|
1169
|
+
},
|
|
1170
|
+
{
|
|
1171
|
+
status: 401,
|
|
1172
|
+
description: 'Admin account required'
|
|
1173
|
+
},
|
|
1174
|
+
{
|
|
1175
|
+
status: 404,
|
|
1176
|
+
description: 'User not found. / Group not found.'
|
|
1177
|
+
},
|
|
1178
|
+
{
|
|
1179
|
+
status: 409,
|
|
1180
|
+
description: 'Permission already exists with provided Path, Type and User. / Permission already exists with provided Path, Type and Group.'
|
|
1089
1181
|
}
|
|
1090
1182
|
]
|
|
1091
1183
|
},
|
|
@@ -1108,6 +1200,14 @@ exports.GENERATED_ROUTES = [
|
|
|
1108
1200
|
{
|
|
1109
1201
|
status: 204,
|
|
1110
1202
|
description: 'No content'
|
|
1203
|
+
},
|
|
1204
|
+
{
|
|
1205
|
+
status: 401,
|
|
1206
|
+
description: 'Admin account required'
|
|
1207
|
+
},
|
|
1208
|
+
{
|
|
1209
|
+
status: 404,
|
|
1210
|
+
description: 'Permission not found.'
|
|
1111
1211
|
}
|
|
1112
1212
|
]
|
|
1113
1213
|
},
|
|
@@ -1136,6 +1236,14 @@ exports.GENERATED_ROUTES = [
|
|
|
1136
1236
|
{
|
|
1137
1237
|
status: 200,
|
|
1138
1238
|
description: 'Ok'
|
|
1239
|
+
},
|
|
1240
|
+
{
|
|
1241
|
+
status: 401,
|
|
1242
|
+
description: 'Admin account required'
|
|
1243
|
+
},
|
|
1244
|
+
{
|
|
1245
|
+
status: 404,
|
|
1246
|
+
description: 'Permission not found.'
|
|
1139
1247
|
}
|
|
1140
1248
|
]
|
|
1141
1249
|
},
|
|
@@ -1400,6 +1508,14 @@ exports.GENERATED_ROUTES = [
|
|
|
1400
1508
|
{
|
|
1401
1509
|
status: 200,
|
|
1402
1510
|
description: 'Ok'
|
|
1511
|
+
},
|
|
1512
|
+
{
|
|
1513
|
+
status: 401,
|
|
1514
|
+
description: 'Admin account required'
|
|
1515
|
+
},
|
|
1516
|
+
{
|
|
1517
|
+
status: 409,
|
|
1518
|
+
description: 'Username already exists.'
|
|
1403
1519
|
}
|
|
1404
1520
|
]
|
|
1405
1521
|
},
|
|
@@ -1428,6 +1544,14 @@ exports.GENERATED_ROUTES = [
|
|
|
1428
1544
|
{
|
|
1429
1545
|
status: 204,
|
|
1430
1546
|
description: 'No content'
|
|
1547
|
+
},
|
|
1548
|
+
{
|
|
1549
|
+
status: 401,
|
|
1550
|
+
description: 'Admin account required, or invalid password'
|
|
1551
|
+
},
|
|
1552
|
+
{
|
|
1553
|
+
status: 404,
|
|
1554
|
+
description: 'User is not found.'
|
|
1431
1555
|
}
|
|
1432
1556
|
]
|
|
1433
1557
|
},
|
|
@@ -1450,6 +1574,14 @@ exports.GENERATED_ROUTES = [
|
|
|
1450
1574
|
{
|
|
1451
1575
|
status: 200,
|
|
1452
1576
|
description: 'Ok'
|
|
1577
|
+
},
|
|
1578
|
+
{
|
|
1579
|
+
status: 401,
|
|
1580
|
+
description: 'Unauthorized'
|
|
1581
|
+
},
|
|
1582
|
+
{
|
|
1583
|
+
status: 404,
|
|
1584
|
+
description: 'User is not found.'
|
|
1453
1585
|
}
|
|
1454
1586
|
]
|
|
1455
1587
|
},
|
|
@@ -1508,6 +1640,22 @@ exports.GENERATED_ROUTES = [
|
|
|
1508
1640
|
{
|
|
1509
1641
|
status: 200,
|
|
1510
1642
|
description: 'Ok'
|
|
1643
|
+
},
|
|
1644
|
+
{
|
|
1645
|
+
status: 401,
|
|
1646
|
+
description: 'Admin account required'
|
|
1647
|
+
},
|
|
1648
|
+
{
|
|
1649
|
+
status: 404,
|
|
1650
|
+
description: 'Unable to find user with <id>'
|
|
1651
|
+
},
|
|
1652
|
+
{
|
|
1653
|
+
status: 405,
|
|
1654
|
+
description: 'Can not update username of user that is created by an external auth provider. / Can not update display name of user that is created by an external auth provider.'
|
|
1655
|
+
},
|
|
1656
|
+
{
|
|
1657
|
+
status: 409,
|
|
1658
|
+
description: 'Username already exists.'
|
|
1511
1659
|
}
|
|
1512
1660
|
]
|
|
1513
1661
|
},
|
|
@@ -1536,6 +1684,14 @@ exports.GENERATED_ROUTES = [
|
|
|
1536
1684
|
{
|
|
1537
1685
|
status: 204,
|
|
1538
1686
|
description: 'No content'
|
|
1687
|
+
},
|
|
1688
|
+
{
|
|
1689
|
+
status: 401,
|
|
1690
|
+
description: 'Admin account required, or invalid password'
|
|
1691
|
+
},
|
|
1692
|
+
{
|
|
1693
|
+
status: 404,
|
|
1694
|
+
description: 'User is not found.'
|
|
1539
1695
|
}
|
|
1540
1696
|
]
|
|
1541
1697
|
},
|
|
@@ -1558,6 +1714,14 @@ exports.GENERATED_ROUTES = [
|
|
|
1558
1714
|
{
|
|
1559
1715
|
status: 200,
|
|
1560
1716
|
description: 'Ok'
|
|
1717
|
+
},
|
|
1718
|
+
{
|
|
1719
|
+
status: 401,
|
|
1720
|
+
description: 'Unauthorized'
|
|
1721
|
+
},
|
|
1722
|
+
{
|
|
1723
|
+
status: 404,
|
|
1724
|
+
description: 'User is not found.'
|
|
1561
1725
|
}
|
|
1562
1726
|
]
|
|
1563
1727
|
},
|
|
@@ -1616,6 +1780,22 @@ exports.GENERATED_ROUTES = [
|
|
|
1616
1780
|
{
|
|
1617
1781
|
status: 200,
|
|
1618
1782
|
description: 'Ok'
|
|
1783
|
+
},
|
|
1784
|
+
{
|
|
1785
|
+
status: 401,
|
|
1786
|
+
description: 'Admin account required'
|
|
1787
|
+
},
|
|
1788
|
+
{
|
|
1789
|
+
status: 404,
|
|
1790
|
+
description: 'Unable to find user with <username>'
|
|
1791
|
+
},
|
|
1792
|
+
{
|
|
1793
|
+
status: 405,
|
|
1794
|
+
description: 'Can not update username of user that is created by an external auth provider. / Can not update display name of user that is created by an external auth provider.'
|
|
1795
|
+
},
|
|
1796
|
+
{
|
|
1797
|
+
status: 409,
|
|
1798
|
+
description: 'Username already exists.'
|
|
1619
1799
|
}
|
|
1620
1800
|
]
|
|
1621
1801
|
},
|
|
@@ -1649,7 +1829,7 @@ exports.GENERATED_ROUTES = [
|
|
|
1649
1829
|
},
|
|
1650
1830
|
{
|
|
1651
1831
|
status: 403,
|
|
1652
|
-
description: 'The client id is unknown'
|
|
1832
|
+
description: 'The client id is unknown. This route runs under a signed-in session, so the caller is authenticated and an unknown client is refused as forbidden; the unauthenticated `POST /SASjsApi/auth/token` answers `401` for the same condition'
|
|
1653
1833
|
}
|
|
1654
1834
|
]
|
|
1655
1835
|
},
|
|
@@ -25,7 +25,7 @@ exports.TAG_CAPABILITIES = {
|
|
|
25
25
|
* operation waits on, and thirty copies of the same sentence would say the same
|
|
26
26
|
* thing thirty times.
|
|
27
27
|
*/
|
|
28
|
-
const
|
|
28
|
+
const 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.';
|
|
29
29
|
const EDITOR = 'Linting and formatting come from @sasjs/lint, which this package does not depend on. They land with the code routes so an editor has one wiring.';
|
|
30
30
|
const 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.';
|
|
31
31
|
const 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.";
|
|
@@ -80,18 +80,20 @@ exports.OVERLAY = {
|
|
|
80
80
|
},
|
|
81
81
|
'POST /SASjsApi/auth/logout': { implemented: true },
|
|
82
82
|
'PATCH /SASjsApi/auth/updatePassword': {
|
|
83
|
-
implemented:
|
|
84
|
-
|
|
83
|
+
implemented: true,
|
|
84
|
+
// As with the permission list: the document's 404 is a caller whose record
|
|
85
|
+
// has gone, which a host's store can see and this package cannot.
|
|
86
|
+
hostResponses: [404]
|
|
85
87
|
},
|
|
86
88
|
// Auth Config - the providers a host was started with, and an LDAP import
|
|
87
89
|
'GET /SASjsApi/authConfig': { implemented: false, reason: HOST_CONFIG },
|
|
88
90
|
'POST /SASjsApi/authConfig/synchroniseWithLDAP': {
|
|
89
91
|
implemented: false,
|
|
90
|
-
reason:
|
|
92
|
+
reason: DIRECTORY
|
|
91
93
|
},
|
|
92
94
|
// Client - the OAuth clients the identity store already holds for sign-in
|
|
93
|
-
'GET /SASjsApi/client': { implemented:
|
|
94
|
-
'POST /SASjsApi/client': { implemented:
|
|
95
|
+
'GET /SASjsApi/client': { implemented: true },
|
|
96
|
+
'POST /SASjsApi/client': { implemented: true },
|
|
95
97
|
// Code - the editor's three calls, and the runtime one
|
|
96
98
|
'POST /SASjsApi/code/execute': { implemented: false, reason: RUNTIME },
|
|
97
99
|
'POST /SASjsApi/code/trigger': { implemented: false, reason: RUNTIME },
|
|
@@ -165,25 +167,13 @@ exports.OVERLAY = {
|
|
|
165
167
|
reason: UNPUBLISH
|
|
166
168
|
},
|
|
167
169
|
// Group - members and the groups themselves
|
|
168
|
-
'GET /SASjsApi/group': { implemented:
|
|
169
|
-
'GET /SASjsApi/group/{uid}': { implemented:
|
|
170
|
-
'GET /SASjsApi/group/by/groupname/{name}': {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
},
|
|
174
|
-
'
|
|
175
|
-
'POST /SASjsApi/group/{groupUid}/{userUid}': {
|
|
176
|
-
implemented: false,
|
|
177
|
-
reason: IDENTITY_RECORDS
|
|
178
|
-
},
|
|
179
|
-
'DELETE /SASjsApi/group/{groupUid}/{userUid}': {
|
|
180
|
-
implemented: false,
|
|
181
|
-
reason: IDENTITY_RECORDS
|
|
182
|
-
},
|
|
183
|
-
'DELETE /SASjsApi/group/{uid}': {
|
|
184
|
-
implemented: false,
|
|
185
|
-
reason: IDENTITY_RECORDS
|
|
186
|
-
},
|
|
170
|
+
'GET /SASjsApi/group': { implemented: true },
|
|
171
|
+
'GET /SASjsApi/group/{uid}': { implemented: true },
|
|
172
|
+
'GET /SASjsApi/group/by/groupname/{name}': { implemented: true },
|
|
173
|
+
'POST /SASjsApi/group': { implemented: true },
|
|
174
|
+
'POST /SASjsApi/group/{groupUid}/{userUid}': { implemented: true },
|
|
175
|
+
'DELETE /SASjsApi/group/{groupUid}/{userUid}': { implemented: true },
|
|
176
|
+
'DELETE /SASjsApi/group/{uid}': { implemented: true },
|
|
187
177
|
// Info - what the host is, and what this caller may use
|
|
188
178
|
'GET /SASjsApi/info': { implemented: false, reason: HOST_CONFIG },
|
|
189
179
|
'GET /SASjsApi/info/authorizedRoutes': {
|
|
@@ -199,16 +189,24 @@ exports.OVERLAY = {
|
|
|
199
189
|
reason: PERMISSIONS
|
|
200
190
|
},
|
|
201
191
|
// Permission - the rules the inventory above is derived from
|
|
202
|
-
'GET /SASjsApi/permission': {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
},
|
|
192
|
+
'GET /SASjsApi/permission': {
|
|
193
|
+
implemented: true,
|
|
194
|
+
// The document states 404 for a caller whose record has gone - a token that
|
|
195
|
+
// outlived its account. Here a token stops resolving when the account does,
|
|
196
|
+
// so this package answers 401 before it gets that far; the host's own store
|
|
197
|
+
// is what can still see the difference.
|
|
198
|
+
hostResponses: [404]
|
|
199
|
+
},
|
|
200
|
+
'POST /SASjsApi/permission': { implemented: true },
|
|
201
|
+
'PATCH /SASjsApi/permission/{uid}': { implemented: true },
|
|
202
|
+
// The three deletes answer 204 here and 200 on the wire: the server's route
|
|
203
|
+
// handlers send `res.status(200).send('Account Deleted!')` and
|
|
204
|
+
// `'Permission Deleted!'`, while tsoa emitted 204 for a void handler, so the
|
|
205
|
+
// document understates the status. Correcting it is a decorator in
|
|
206
|
+
// sasjs/server (`@SuccessResponse('200', ...)`), and this package follows the
|
|
207
|
+
// document until that release lands - a local 200 would fail the schema check
|
|
208
|
+
// that keeps this table honest.
|
|
209
|
+
'DELETE /SASjsApi/permission/{uid}': { implemented: true },
|
|
212
210
|
// Session - the caller's own session, then the record behind a triggered one
|
|
213
211
|
'GET /SASjsApi/session': {
|
|
214
212
|
implemented: true,
|
|
@@ -235,29 +233,26 @@ exports.OVERLAY = {
|
|
|
235
233
|
'POST /SASjsApi/stp/execute': { implemented: false, reason: RUNTIME },
|
|
236
234
|
'POST /SASjsApi/stp/trigger': { implemented: false, reason: RUNTIME },
|
|
237
235
|
// User - the accounts the identity store already holds for sign-in
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
'
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
},
|
|
249
|
-
'PATCH /SASjsApi/user/
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
},
|
|
257
|
-
'DELETE /SASjsApi/user/by/username/{username}': {
|
|
258
|
-
implemented: false,
|
|
259
|
-
reason: IDENTITY_RECORDS
|
|
260
|
-
}
|
|
236
|
+
// Reading accounts is open to any authenticated caller, which is what
|
|
237
|
+
// sasjs/server's routes do (`authenticateAccessToken` only): the document once
|
|
238
|
+
// said `Admin account required` here, and sasjs/server#551 corrected it to
|
|
239
|
+
// `Unauthorized` because that is the refusal a caller actually receives. The
|
|
240
|
+
// breadth is the server's behaviour, copied deliberately - the auto-exec code
|
|
241
|
+
// is the one field withheld from anyone but an administrator or the account
|
|
242
|
+
// itself.
|
|
243
|
+
'GET /SASjsApi/user': { implemented: true },
|
|
244
|
+
'GET /SASjsApi/user/{uid}': { implemented: true },
|
|
245
|
+
'GET /SASjsApi/user/by/username/{username}': { implemented: true },
|
|
246
|
+
'POST /SASjsApi/user': { implemented: true },
|
|
247
|
+
'PATCH /SASjsApi/user/{uid}': { implemented: true },
|
|
248
|
+
'PATCH /SASjsApi/user/by/username/{username}': { implemented: true },
|
|
249
|
+
// The document also marks `password` optional on these deletes, while the
|
|
250
|
+
// server's schema requires it for anyone who is not an administrator, and for
|
|
251
|
+
// an account deleting itself. A host should treat a passwordless delete from a
|
|
252
|
+
// non-admin as the refusal it is; this package answers 401 `Invalid password.`
|
|
253
|
+
// where the server's schema answers 400 `"password" is required`.
|
|
254
|
+
'DELETE /SASjsApi/user/{uid}': { implemented: true },
|
|
255
|
+
'DELETE /SASjsApi/user/by/username/{username}': { implemented: true }
|
|
261
256
|
};
|
|
262
257
|
/** Every method the table may state, in the order a diff reads best. */
|
|
263
258
|
exports.METHODS = ['GET', 'POST', 'PATCH', 'DELETE', 'PUT'];
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The administration routes' conformance corpus: users, groups, permission rules
|
|
3
|
+
* and clients, as requests in and answers out.
|
|
4
|
+
*
|
|
5
|
+
* Every status the document states for these routes has a case here - that is
|
|
6
|
+
* what `spec/corpus-parity.spec.ts` enforces in both directions - so a refusal
|
|
7
|
+
* is part of the contract rather than something a reader has to infer from the
|
|
8
|
+
* controller.
|
|
9
|
+
*
|
|
10
|
+
* The fixtures are small on purpose: one administrator, one restricted user, the
|
|
11
|
+
* two groups they belong to, three rules, and - for the refusals that only an
|
|
12
|
+
* externally-managed account can provoke - a provider-managed user and group and
|
|
13
|
+
* the reserved `public` group.
|
|
14
|
+
*/
|
|
15
|
+
import type { CorpusCase } from './drive.js';
|
|
16
|
+
import { type IdentityFixture } from '../identity/fixture.js';
|
|
17
|
+
/** The default identity, with an administrator and the restricted user signed in. */
|
|
18
|
+
export declare const ADMIN_SIGNED_IN: IdentityFixture;
|
|
19
|
+
/**
|
|
20
|
+
* The same identity, plus what the provider and public-group refusals need: an
|
|
21
|
+
* account and a group managed by an external provider, and the reserved group.
|
|
22
|
+
*/
|
|
23
|
+
export declare const PROVIDER_MANAGED: IdentityFixture;
|
|
24
|
+
export declare const RECORD_CORPUS: CorpusCase[];
|
|
25
|
+
//# sourceMappingURL=records.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"records.d.ts","sourceRoot":"","sources":["../../../src/corpus/records.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAC5C,OAAO,EAEL,KAAK,eAAe,EAErB,MAAM,wBAAwB,CAAA;AAkB/B,qFAAqF;AACrF,eAAO,MAAM,eAAe,EAAE,eAG7B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,eA0C9B,CAAA;AAOD,eAAO,MAAM,aAAa,EAAE,UAAU,EA0oCrC,CAAA"}
|