@backstage/backend-app-api 0.7.0-next.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/CHANGELOG.md +38 -0
- package/alpha/package.json +1 -1
- package/config.d.ts +100 -0
- package/dist/index.cjs.js +762 -589
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/package.json +10 -10
package/dist/index.cjs.js
CHANGED
|
@@ -21,11 +21,11 @@ var crypto = require('crypto');
|
|
|
21
21
|
var winston = require('winston');
|
|
22
22
|
var backendPluginApi = require('@backstage/backend-plugin-api');
|
|
23
23
|
var alpha = require('@backstage/backend-plugin-api/alpha');
|
|
24
|
-
var jose = require('jose');
|
|
25
|
-
var pluginAuthNode = require('@backstage/plugin-auth-node');
|
|
26
|
-
var uuid = require('uuid');
|
|
27
24
|
var luxon = require('luxon');
|
|
28
25
|
var backendCommon = require('@backstage/backend-common');
|
|
26
|
+
var jose = require('jose');
|
|
27
|
+
var uuid = require('uuid');
|
|
28
|
+
var pluginAuthNode = require('@backstage/plugin-auth-node');
|
|
29
29
|
var backendAppApi = require('@backstage/backend-app-api');
|
|
30
30
|
var cookie = require('cookie');
|
|
31
31
|
var Router = require('express-promise-router');
|
|
@@ -612,31 +612,31 @@ function applyInternalErrorFilter(error, logger) {
|
|
|
612
612
|
return error;
|
|
613
613
|
}
|
|
614
614
|
|
|
615
|
-
var __accessCheck$
|
|
615
|
+
var __accessCheck$e = (obj, member, msg) => {
|
|
616
616
|
if (!member.has(obj))
|
|
617
617
|
throw TypeError("Cannot " + msg);
|
|
618
618
|
};
|
|
619
|
-
var __privateGet$
|
|
620
|
-
__accessCheck$
|
|
619
|
+
var __privateGet$c = (obj, member, getter) => {
|
|
620
|
+
__accessCheck$e(obj, member, "read from private field");
|
|
621
621
|
return getter ? getter.call(obj) : member.get(obj);
|
|
622
622
|
};
|
|
623
|
-
var __privateAdd$
|
|
623
|
+
var __privateAdd$e = (obj, member, value) => {
|
|
624
624
|
if (member.has(obj))
|
|
625
625
|
throw TypeError("Cannot add the same private member more than once");
|
|
626
626
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
627
627
|
};
|
|
628
|
-
var __privateSet$
|
|
629
|
-
__accessCheck$
|
|
628
|
+
var __privateSet$a = (obj, member, value, setter) => {
|
|
629
|
+
__accessCheck$e(obj, member, "write to private field");
|
|
630
630
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
631
631
|
return value;
|
|
632
632
|
};
|
|
633
633
|
var _config, _logger;
|
|
634
634
|
const _MiddlewareFactory = class _MiddlewareFactory {
|
|
635
635
|
constructor(options) {
|
|
636
|
-
__privateAdd$
|
|
637
|
-
__privateAdd$
|
|
638
|
-
__privateSet$
|
|
639
|
-
__privateSet$
|
|
636
|
+
__privateAdd$e(this, _config, void 0);
|
|
637
|
+
__privateAdd$e(this, _logger, void 0);
|
|
638
|
+
__privateSet$a(this, _config, options.config);
|
|
639
|
+
__privateSet$a(this, _logger, options.logger);
|
|
640
640
|
}
|
|
641
641
|
/**
|
|
642
642
|
* Creates a new {@link MiddlewareFactory}.
|
|
@@ -682,7 +682,7 @@ const _MiddlewareFactory = class _MiddlewareFactory {
|
|
|
682
682
|
* @returns An Express request handler
|
|
683
683
|
*/
|
|
684
684
|
logging() {
|
|
685
|
-
const logger = __privateGet$
|
|
685
|
+
const logger = __privateGet$c(this, _logger).child({
|
|
686
686
|
type: "incomingRequest"
|
|
687
687
|
});
|
|
688
688
|
return morgan__default.default("combined", {
|
|
@@ -706,7 +706,7 @@ const _MiddlewareFactory = class _MiddlewareFactory {
|
|
|
706
706
|
* @returns An Express request handler
|
|
707
707
|
*/
|
|
708
708
|
helmet() {
|
|
709
|
-
return helmet__default.default(readHelmetOptions(__privateGet$
|
|
709
|
+
return helmet__default.default(readHelmetOptions(__privateGet$c(this, _config).getOptionalConfig("backend")));
|
|
710
710
|
}
|
|
711
711
|
/**
|
|
712
712
|
* Returns a middleware that implements the cors library.
|
|
@@ -721,7 +721,7 @@ const _MiddlewareFactory = class _MiddlewareFactory {
|
|
|
721
721
|
* @returns An Express request handler
|
|
722
722
|
*/
|
|
723
723
|
cors() {
|
|
724
|
-
return cors__default.default(readCorsOptions(__privateGet$
|
|
724
|
+
return cors__default.default(readCorsOptions(__privateGet$c(this, _config).getOptionalConfig("backend")));
|
|
725
725
|
}
|
|
726
726
|
/**
|
|
727
727
|
* Express middleware to handle errors during request processing.
|
|
@@ -746,7 +746,7 @@ const _MiddlewareFactory = class _MiddlewareFactory {
|
|
|
746
746
|
error(options = {}) {
|
|
747
747
|
var _a;
|
|
748
748
|
const showStackTraces = (_a = options.showStackTraces) != null ? _a : process.env.NODE_ENV === "development";
|
|
749
|
-
const logger = __privateGet$
|
|
749
|
+
const logger = __privateGet$c(this, _logger).child({
|
|
750
750
|
type: "errorHandler"
|
|
751
751
|
});
|
|
752
752
|
return (rawError, req, res, next) => {
|
|
@@ -805,31 +805,31 @@ const escapeRegExp = (text) => {
|
|
|
805
805
|
return text.replace(/[.*+?^${}(\)|[\]\\]/g, "\\$&");
|
|
806
806
|
};
|
|
807
807
|
|
|
808
|
-
var __accessCheck$
|
|
808
|
+
var __accessCheck$d = (obj, member, msg) => {
|
|
809
809
|
if (!member.has(obj))
|
|
810
810
|
throw TypeError("Cannot " + msg);
|
|
811
811
|
};
|
|
812
|
-
var __privateGet$
|
|
813
|
-
__accessCheck$
|
|
812
|
+
var __privateGet$b = (obj, member, getter) => {
|
|
813
|
+
__accessCheck$d(obj, member, "read from private field");
|
|
814
814
|
return getter ? getter.call(obj) : member.get(obj);
|
|
815
815
|
};
|
|
816
|
-
var __privateAdd$
|
|
816
|
+
var __privateAdd$d = (obj, member, value) => {
|
|
817
817
|
if (member.has(obj))
|
|
818
818
|
throw TypeError("Cannot add the same private member more than once");
|
|
819
819
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
820
820
|
};
|
|
821
|
-
var __privateSet$
|
|
822
|
-
__accessCheck$
|
|
821
|
+
var __privateSet$9 = (obj, member, value, setter) => {
|
|
822
|
+
__accessCheck$d(obj, member, "write to private field");
|
|
823
823
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
824
824
|
return value;
|
|
825
825
|
};
|
|
826
826
|
var _winston, _addRedactions;
|
|
827
827
|
const _WinstonLogger = class _WinstonLogger {
|
|
828
828
|
constructor(winston, addRedactions) {
|
|
829
|
-
__privateAdd$
|
|
830
|
-
__privateAdd$
|
|
831
|
-
__privateSet$
|
|
832
|
-
__privateSet$
|
|
829
|
+
__privateAdd$d(this, _winston, void 0);
|
|
830
|
+
__privateAdd$d(this, _addRedactions, void 0);
|
|
831
|
+
__privateSet$9(this, _winston, winston);
|
|
832
|
+
__privateSet$9(this, _addRedactions, addRedactions);
|
|
833
833
|
}
|
|
834
834
|
/**
|
|
835
835
|
* Creates a {@link WinstonLogger} instance.
|
|
@@ -914,44 +914,44 @@ const _WinstonLogger = class _WinstonLogger {
|
|
|
914
914
|
);
|
|
915
915
|
}
|
|
916
916
|
error(message, meta) {
|
|
917
|
-
__privateGet$
|
|
917
|
+
__privateGet$b(this, _winston).error(message, meta);
|
|
918
918
|
}
|
|
919
919
|
warn(message, meta) {
|
|
920
|
-
__privateGet$
|
|
920
|
+
__privateGet$b(this, _winston).warn(message, meta);
|
|
921
921
|
}
|
|
922
922
|
info(message, meta) {
|
|
923
|
-
__privateGet$
|
|
923
|
+
__privateGet$b(this, _winston).info(message, meta);
|
|
924
924
|
}
|
|
925
925
|
debug(message, meta) {
|
|
926
|
-
__privateGet$
|
|
926
|
+
__privateGet$b(this, _winston).debug(message, meta);
|
|
927
927
|
}
|
|
928
928
|
child(meta) {
|
|
929
|
-
return new _WinstonLogger(__privateGet$
|
|
929
|
+
return new _WinstonLogger(__privateGet$b(this, _winston).child(meta));
|
|
930
930
|
}
|
|
931
931
|
addRedactions(redactions) {
|
|
932
932
|
var _a;
|
|
933
|
-
(_a = __privateGet$
|
|
933
|
+
(_a = __privateGet$b(this, _addRedactions)) == null ? void 0 : _a.call(this, redactions);
|
|
934
934
|
}
|
|
935
935
|
};
|
|
936
936
|
_winston = new WeakMap();
|
|
937
937
|
_addRedactions = new WeakMap();
|
|
938
938
|
let WinstonLogger = _WinstonLogger;
|
|
939
939
|
|
|
940
|
-
var __accessCheck$
|
|
940
|
+
var __accessCheck$c = (obj, member, msg) => {
|
|
941
941
|
if (!member.has(obj))
|
|
942
942
|
throw TypeError("Cannot " + msg);
|
|
943
943
|
};
|
|
944
|
-
var __privateGet$
|
|
945
|
-
__accessCheck$
|
|
944
|
+
var __privateGet$a = (obj, member, getter) => {
|
|
945
|
+
__accessCheck$c(obj, member, "read from private field");
|
|
946
946
|
return getter ? getter.call(obj) : member.get(obj);
|
|
947
947
|
};
|
|
948
|
-
var __privateAdd$
|
|
948
|
+
var __privateAdd$c = (obj, member, value) => {
|
|
949
949
|
if (member.has(obj))
|
|
950
950
|
throw TypeError("Cannot add the same private member more than once");
|
|
951
951
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
952
952
|
};
|
|
953
|
-
var __privateSet$
|
|
954
|
-
__accessCheck$
|
|
953
|
+
var __privateSet$8 = (obj, member, value, setter) => {
|
|
954
|
+
__accessCheck$c(obj, member, "write to private field");
|
|
955
955
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
956
956
|
return value;
|
|
957
957
|
};
|
|
@@ -959,25 +959,25 @@ var _hasStarted$1, _startupTasks$1, _hasShutdown, _shutdownTasks;
|
|
|
959
959
|
class BackendLifecycleImpl {
|
|
960
960
|
constructor(logger) {
|
|
961
961
|
this.logger = logger;
|
|
962
|
-
__privateAdd$
|
|
963
|
-
__privateAdd$
|
|
964
|
-
__privateAdd$
|
|
965
|
-
__privateAdd$
|
|
962
|
+
__privateAdd$c(this, _hasStarted$1, false);
|
|
963
|
+
__privateAdd$c(this, _startupTasks$1, []);
|
|
964
|
+
__privateAdd$c(this, _hasShutdown, false);
|
|
965
|
+
__privateAdd$c(this, _shutdownTasks, []);
|
|
966
966
|
}
|
|
967
967
|
addStartupHook(hook, options) {
|
|
968
|
-
if (__privateGet$
|
|
968
|
+
if (__privateGet$a(this, _hasStarted$1)) {
|
|
969
969
|
throw new Error("Attempted to add startup hook after startup");
|
|
970
970
|
}
|
|
971
|
-
__privateGet$
|
|
971
|
+
__privateGet$a(this, _startupTasks$1).push({ hook, options });
|
|
972
972
|
}
|
|
973
973
|
async startup() {
|
|
974
|
-
if (__privateGet$
|
|
974
|
+
if (__privateGet$a(this, _hasStarted$1)) {
|
|
975
975
|
return;
|
|
976
976
|
}
|
|
977
|
-
__privateSet$
|
|
978
|
-
this.logger.debug(`Running ${__privateGet$
|
|
977
|
+
__privateSet$8(this, _hasStarted$1, true);
|
|
978
|
+
this.logger.debug(`Running ${__privateGet$a(this, _startupTasks$1).length} startup tasks...`);
|
|
979
979
|
await Promise.all(
|
|
980
|
-
__privateGet$
|
|
980
|
+
__privateGet$a(this, _startupTasks$1).map(async ({ hook, options }) => {
|
|
981
981
|
var _a;
|
|
982
982
|
const logger = (_a = options == null ? void 0 : options.logger) != null ? _a : this.logger;
|
|
983
983
|
try {
|
|
@@ -990,21 +990,21 @@ class BackendLifecycleImpl {
|
|
|
990
990
|
);
|
|
991
991
|
}
|
|
992
992
|
addShutdownHook(hook, options) {
|
|
993
|
-
if (__privateGet$
|
|
993
|
+
if (__privateGet$a(this, _hasShutdown)) {
|
|
994
994
|
throw new Error("Attempted to add shutdown hook after shutdown");
|
|
995
995
|
}
|
|
996
|
-
__privateGet$
|
|
996
|
+
__privateGet$a(this, _shutdownTasks).push({ hook, options });
|
|
997
997
|
}
|
|
998
998
|
async shutdown() {
|
|
999
|
-
if (__privateGet$
|
|
999
|
+
if (__privateGet$a(this, _hasShutdown)) {
|
|
1000
1000
|
return;
|
|
1001
1001
|
}
|
|
1002
|
-
__privateSet$
|
|
1002
|
+
__privateSet$8(this, _hasShutdown, true);
|
|
1003
1003
|
this.logger.debug(
|
|
1004
|
-
`Running ${__privateGet$
|
|
1004
|
+
`Running ${__privateGet$a(this, _shutdownTasks).length} shutdown tasks...`
|
|
1005
1005
|
);
|
|
1006
1006
|
await Promise.all(
|
|
1007
|
-
__privateGet$
|
|
1007
|
+
__privateGet$a(this, _shutdownTasks).map(async ({ hook, options }) => {
|
|
1008
1008
|
var _a;
|
|
1009
1009
|
const logger = (_a = options == null ? void 0 : options.logger) != null ? _a : this.logger;
|
|
1010
1010
|
try {
|
|
@@ -1031,21 +1031,21 @@ const rootLifecycleServiceFactory = backendPluginApi.createServiceFactory({
|
|
|
1031
1031
|
}
|
|
1032
1032
|
});
|
|
1033
1033
|
|
|
1034
|
-
var __accessCheck$
|
|
1034
|
+
var __accessCheck$b = (obj, member, msg) => {
|
|
1035
1035
|
if (!member.has(obj))
|
|
1036
1036
|
throw TypeError("Cannot " + msg);
|
|
1037
1037
|
};
|
|
1038
|
-
var __privateGet$
|
|
1039
|
-
__accessCheck$
|
|
1038
|
+
var __privateGet$9 = (obj, member, getter) => {
|
|
1039
|
+
__accessCheck$b(obj, member, "read from private field");
|
|
1040
1040
|
return getter ? getter.call(obj) : member.get(obj);
|
|
1041
1041
|
};
|
|
1042
|
-
var __privateAdd$
|
|
1042
|
+
var __privateAdd$b = (obj, member, value) => {
|
|
1043
1043
|
if (member.has(obj))
|
|
1044
1044
|
throw TypeError("Cannot add the same private member more than once");
|
|
1045
1045
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1046
1046
|
};
|
|
1047
|
-
var __privateSet$
|
|
1048
|
-
__accessCheck$
|
|
1047
|
+
var __privateSet$7 = (obj, member, value, setter) => {
|
|
1048
|
+
__accessCheck$b(obj, member, "write to private field");
|
|
1049
1049
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1050
1050
|
return value;
|
|
1051
1051
|
};
|
|
@@ -1055,25 +1055,25 @@ class BackendPluginLifecycleImpl {
|
|
|
1055
1055
|
this.logger = logger;
|
|
1056
1056
|
this.rootLifecycle = rootLifecycle;
|
|
1057
1057
|
this.pluginMetadata = pluginMetadata;
|
|
1058
|
-
__privateAdd$
|
|
1059
|
-
__privateAdd$
|
|
1058
|
+
__privateAdd$b(this, _hasStarted, false);
|
|
1059
|
+
__privateAdd$b(this, _startupTasks, []);
|
|
1060
1060
|
}
|
|
1061
1061
|
addStartupHook(hook, options) {
|
|
1062
|
-
if (__privateGet$
|
|
1062
|
+
if (__privateGet$9(this, _hasStarted)) {
|
|
1063
1063
|
throw new Error("Attempted to add startup hook after startup");
|
|
1064
1064
|
}
|
|
1065
|
-
__privateGet$
|
|
1065
|
+
__privateGet$9(this, _startupTasks).push({ hook, options });
|
|
1066
1066
|
}
|
|
1067
1067
|
async startup() {
|
|
1068
|
-
if (__privateGet$
|
|
1068
|
+
if (__privateGet$9(this, _hasStarted)) {
|
|
1069
1069
|
return;
|
|
1070
1070
|
}
|
|
1071
|
-
__privateSet$
|
|
1071
|
+
__privateSet$7(this, _hasStarted, true);
|
|
1072
1072
|
this.logger.debug(
|
|
1073
|
-
`Running ${__privateGet$
|
|
1073
|
+
`Running ${__privateGet$9(this, _startupTasks).length} plugin startup tasks...`
|
|
1074
1074
|
);
|
|
1075
1075
|
await Promise.all(
|
|
1076
|
-
__privateGet$
|
|
1076
|
+
__privateGet$9(this, _startupTasks).map(async ({ hook, options }) => {
|
|
1077
1077
|
var _a;
|
|
1078
1078
|
const logger = (_a = options == null ? void 0 : options.logger) != null ? _a : this.logger;
|
|
1079
1079
|
try {
|
|
@@ -1111,26 +1111,26 @@ const lifecycleServiceFactory = backendPluginApi.createServiceFactory({
|
|
|
1111
1111
|
}
|
|
1112
1112
|
});
|
|
1113
1113
|
|
|
1114
|
-
var __accessCheck$
|
|
1114
|
+
var __accessCheck$a = (obj, member, msg) => {
|
|
1115
1115
|
if (!member.has(obj))
|
|
1116
1116
|
throw TypeError("Cannot " + msg);
|
|
1117
1117
|
};
|
|
1118
|
-
var __privateGet$
|
|
1119
|
-
__accessCheck$
|
|
1118
|
+
var __privateGet$8 = (obj, member, getter) => {
|
|
1119
|
+
__accessCheck$a(obj, member, "read from private field");
|
|
1120
1120
|
return getter ? getter.call(obj) : member.get(obj);
|
|
1121
1121
|
};
|
|
1122
|
-
var __privateAdd$
|
|
1122
|
+
var __privateAdd$a = (obj, member, value) => {
|
|
1123
1123
|
if (member.has(obj))
|
|
1124
1124
|
throw TypeError("Cannot add the same private member more than once");
|
|
1125
1125
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1126
1126
|
};
|
|
1127
|
-
var __privateSet$
|
|
1128
|
-
__accessCheck$
|
|
1127
|
+
var __privateSet$6 = (obj, member, value, setter) => {
|
|
1128
|
+
__accessCheck$a(obj, member, "write to private field");
|
|
1129
1129
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1130
1130
|
return value;
|
|
1131
1131
|
};
|
|
1132
|
-
var __privateMethod$
|
|
1133
|
-
__accessCheck$
|
|
1132
|
+
var __privateMethod$7 = (obj, member, method) => {
|
|
1133
|
+
__accessCheck$a(obj, member, "access private method");
|
|
1134
1134
|
return method;
|
|
1135
1135
|
};
|
|
1136
1136
|
var _nodeIds, _cycleKeys, _getCycleKey, getCycleKey_fn, _nodes, _allProvided;
|
|
@@ -1150,21 +1150,21 @@ class Node {
|
|
|
1150
1150
|
}
|
|
1151
1151
|
const _CycleKeySet = class _CycleKeySet {
|
|
1152
1152
|
constructor(nodes) {
|
|
1153
|
-
__privateAdd$
|
|
1154
|
-
__privateAdd$
|
|
1155
|
-
__privateAdd$
|
|
1156
|
-
__privateSet$
|
|
1157
|
-
__privateSet$
|
|
1153
|
+
__privateAdd$a(this, _getCycleKey);
|
|
1154
|
+
__privateAdd$a(this, _nodeIds, void 0);
|
|
1155
|
+
__privateAdd$a(this, _cycleKeys, void 0);
|
|
1156
|
+
__privateSet$6(this, _nodeIds, new Map(nodes.map((n, i) => [n.value, i])));
|
|
1157
|
+
__privateSet$6(this, _cycleKeys, /* @__PURE__ */ new Set());
|
|
1158
1158
|
}
|
|
1159
1159
|
static from(nodes) {
|
|
1160
1160
|
return new _CycleKeySet(nodes);
|
|
1161
1161
|
}
|
|
1162
1162
|
tryAdd(path) {
|
|
1163
|
-
const cycleKey = __privateMethod$
|
|
1164
|
-
if (__privateGet$
|
|
1163
|
+
const cycleKey = __privateMethod$7(this, _getCycleKey, getCycleKey_fn).call(this, path);
|
|
1164
|
+
if (__privateGet$8(this, _cycleKeys).has(cycleKey)) {
|
|
1165
1165
|
return false;
|
|
1166
1166
|
}
|
|
1167
|
-
__privateGet$
|
|
1167
|
+
__privateGet$8(this, _cycleKeys).add(cycleKey);
|
|
1168
1168
|
return true;
|
|
1169
1169
|
}
|
|
1170
1170
|
};
|
|
@@ -1172,18 +1172,18 @@ _nodeIds = new WeakMap();
|
|
|
1172
1172
|
_cycleKeys = new WeakMap();
|
|
1173
1173
|
_getCycleKey = new WeakSet();
|
|
1174
1174
|
getCycleKey_fn = function(path) {
|
|
1175
|
-
return path.map((n) => __privateGet$
|
|
1175
|
+
return path.map((n) => __privateGet$8(this, _nodeIds).get(n)).sort().join(",");
|
|
1176
1176
|
};
|
|
1177
1177
|
let CycleKeySet = _CycleKeySet;
|
|
1178
1178
|
const _DependencyGraph = class _DependencyGraph {
|
|
1179
1179
|
constructor(nodes) {
|
|
1180
|
-
__privateAdd$
|
|
1181
|
-
__privateAdd$
|
|
1182
|
-
__privateSet$
|
|
1183
|
-
__privateSet$
|
|
1184
|
-
for (const node of __privateGet$
|
|
1180
|
+
__privateAdd$a(this, _nodes, void 0);
|
|
1181
|
+
__privateAdd$a(this, _allProvided, void 0);
|
|
1182
|
+
__privateSet$6(this, _nodes, nodes);
|
|
1183
|
+
__privateSet$6(this, _allProvided, /* @__PURE__ */ new Set());
|
|
1184
|
+
for (const node of __privateGet$8(this, _nodes).values()) {
|
|
1185
1185
|
for (const produced of node.provides) {
|
|
1186
|
-
__privateGet$
|
|
1186
|
+
__privateGet$8(this, _allProvided).add(produced);
|
|
1187
1187
|
}
|
|
1188
1188
|
}
|
|
1189
1189
|
}
|
|
@@ -1207,9 +1207,9 @@ const _DependencyGraph = class _DependencyGraph {
|
|
|
1207
1207
|
*/
|
|
1208
1208
|
findUnsatisfiedDeps() {
|
|
1209
1209
|
const unsatisfiedDependencies = [];
|
|
1210
|
-
for (const node of __privateGet$
|
|
1210
|
+
for (const node of __privateGet$8(this, _nodes).values()) {
|
|
1211
1211
|
const unsatisfied = Array.from(node.consumes).filter(
|
|
1212
|
-
(id) => !__privateGet$
|
|
1212
|
+
(id) => !__privateGet$8(this, _allProvided).has(id)
|
|
1213
1213
|
);
|
|
1214
1214
|
if (unsatisfied.length > 0) {
|
|
1215
1215
|
unsatisfiedDependencies.push({ value: node.value, unsatisfied });
|
|
@@ -1229,8 +1229,8 @@ const _DependencyGraph = class _DependencyGraph {
|
|
|
1229
1229
|
* form a cycle, with the same node as the first and last element of the array.
|
|
1230
1230
|
*/
|
|
1231
1231
|
*detectCircularDependencies() {
|
|
1232
|
-
const cycleKeys = CycleKeySet.from(__privateGet$
|
|
1233
|
-
for (const startNode of __privateGet$
|
|
1232
|
+
const cycleKeys = CycleKeySet.from(__privateGet$8(this, _nodes));
|
|
1233
|
+
for (const startNode of __privateGet$8(this, _nodes)) {
|
|
1234
1234
|
const visited = /* @__PURE__ */ new Set();
|
|
1235
1235
|
const stack = new Array([
|
|
1236
1236
|
startNode,
|
|
@@ -1243,7 +1243,7 @@ const _DependencyGraph = class _DependencyGraph {
|
|
|
1243
1243
|
}
|
|
1244
1244
|
visited.add(node);
|
|
1245
1245
|
for (const consumed of node.consumes) {
|
|
1246
|
-
const providerNodes = __privateGet$
|
|
1246
|
+
const providerNodes = __privateGet$8(this, _nodes).filter(
|
|
1247
1247
|
(other) => other.provides.has(consumed)
|
|
1248
1248
|
);
|
|
1249
1249
|
for (const provider of providerNodes) {
|
|
@@ -1272,9 +1272,9 @@ const _DependencyGraph = class _DependencyGraph {
|
|
|
1272
1272
|
* Dependencies of nodes that are not produced by any other nodes will be ignored.
|
|
1273
1273
|
*/
|
|
1274
1274
|
async parallelTopologicalTraversal(fn) {
|
|
1275
|
-
const allProvided = __privateGet$
|
|
1275
|
+
const allProvided = __privateGet$8(this, _allProvided);
|
|
1276
1276
|
const producedSoFar = /* @__PURE__ */ new Set();
|
|
1277
|
-
const waiting = new Set(__privateGet$
|
|
1277
|
+
const waiting = new Set(__privateGet$8(this, _nodes).values());
|
|
1278
1278
|
const visited = /* @__PURE__ */ new Set();
|
|
1279
1279
|
const results = new Array();
|
|
1280
1280
|
let inFlight = 0;
|
|
@@ -1320,26 +1320,26 @@ _nodes = new WeakMap();
|
|
|
1320
1320
|
_allProvided = new WeakMap();
|
|
1321
1321
|
let DependencyGraph = _DependencyGraph;
|
|
1322
1322
|
|
|
1323
|
-
var __accessCheck$
|
|
1323
|
+
var __accessCheck$9 = (obj, member, msg) => {
|
|
1324
1324
|
if (!member.has(obj))
|
|
1325
1325
|
throw TypeError("Cannot " + msg);
|
|
1326
1326
|
};
|
|
1327
|
-
var __privateGet$
|
|
1328
|
-
__accessCheck$
|
|
1327
|
+
var __privateGet$7 = (obj, member, getter) => {
|
|
1328
|
+
__accessCheck$9(obj, member, "read from private field");
|
|
1329
1329
|
return getter ? getter.call(obj) : member.get(obj);
|
|
1330
1330
|
};
|
|
1331
|
-
var __privateAdd$
|
|
1331
|
+
var __privateAdd$9 = (obj, member, value) => {
|
|
1332
1332
|
if (member.has(obj))
|
|
1333
1333
|
throw TypeError("Cannot add the same private member more than once");
|
|
1334
1334
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1335
1335
|
};
|
|
1336
|
-
var __privateSet$
|
|
1337
|
-
__accessCheck$
|
|
1336
|
+
var __privateSet$5 = (obj, member, value, setter) => {
|
|
1337
|
+
__accessCheck$9(obj, member, "write to private field");
|
|
1338
1338
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1339
1339
|
return value;
|
|
1340
1340
|
};
|
|
1341
|
-
var __privateMethod$
|
|
1342
|
-
__accessCheck$
|
|
1341
|
+
var __privateMethod$6 = (obj, member, method) => {
|
|
1342
|
+
__accessCheck$9(obj, member, "access private method");
|
|
1343
1343
|
return method;
|
|
1344
1344
|
};
|
|
1345
1345
|
var _providedFactories, _loadedDefaultFactories, _implementations, _rootServiceImplementations, _addedFactoryIds, _instantiatedFactories, _resolveFactory, resolveFactory_fn, _checkForMissingDeps, checkForMissingDeps_fn;
|
|
@@ -1362,19 +1362,19 @@ const pluginMetadataServiceFactory = backendPluginApi.createServiceFactory(
|
|
|
1362
1362
|
);
|
|
1363
1363
|
const _ServiceRegistry = class _ServiceRegistry {
|
|
1364
1364
|
constructor(factories) {
|
|
1365
|
-
__privateAdd$
|
|
1366
|
-
__privateAdd$
|
|
1367
|
-
__privateAdd$
|
|
1368
|
-
__privateAdd$
|
|
1369
|
-
__privateAdd$
|
|
1370
|
-
__privateAdd$
|
|
1371
|
-
__privateAdd$
|
|
1372
|
-
__privateAdd$
|
|
1373
|
-
__privateSet$
|
|
1365
|
+
__privateAdd$9(this, _resolveFactory);
|
|
1366
|
+
__privateAdd$9(this, _checkForMissingDeps);
|
|
1367
|
+
__privateAdd$9(this, _providedFactories, void 0);
|
|
1368
|
+
__privateAdd$9(this, _loadedDefaultFactories, void 0);
|
|
1369
|
+
__privateAdd$9(this, _implementations, void 0);
|
|
1370
|
+
__privateAdd$9(this, _rootServiceImplementations, /* @__PURE__ */ new Map());
|
|
1371
|
+
__privateAdd$9(this, _addedFactoryIds, /* @__PURE__ */ new Set());
|
|
1372
|
+
__privateAdd$9(this, _instantiatedFactories, /* @__PURE__ */ new Set());
|
|
1373
|
+
__privateSet$5(this, _providedFactories, new Map(
|
|
1374
1374
|
factories.map((sf) => [sf.service.id, toInternalServiceFactory(sf)])
|
|
1375
1375
|
));
|
|
1376
|
-
__privateSet$
|
|
1377
|
-
__privateSet$
|
|
1376
|
+
__privateSet$5(this, _loadedDefaultFactories, /* @__PURE__ */ new Map());
|
|
1377
|
+
__privateSet$5(this, _implementations, /* @__PURE__ */ new Map());
|
|
1378
1378
|
}
|
|
1379
1379
|
static create(factories) {
|
|
1380
1380
|
const registry = new _ServiceRegistry(factories);
|
|
@@ -1383,7 +1383,7 @@ const _ServiceRegistry = class _ServiceRegistry {
|
|
|
1383
1383
|
}
|
|
1384
1384
|
checkForCircularDeps() {
|
|
1385
1385
|
const graph = DependencyGraph.fromIterable(
|
|
1386
|
-
Array.from(__privateGet$
|
|
1386
|
+
Array.from(__privateGet$7(this, _providedFactories)).map(
|
|
1387
1387
|
([serviceId, serviceFactory]) => ({
|
|
1388
1388
|
value: serviceId,
|
|
1389
1389
|
provides: [serviceId],
|
|
@@ -1405,21 +1405,21 @@ const _ServiceRegistry = class _ServiceRegistry {
|
|
|
1405
1405
|
`The ${backendPluginApi.coreServices.pluginMetadata.id} service cannot be overridden`
|
|
1406
1406
|
);
|
|
1407
1407
|
}
|
|
1408
|
-
if (__privateGet$
|
|
1408
|
+
if (__privateGet$7(this, _addedFactoryIds).has(factoryId)) {
|
|
1409
1409
|
throw new Error(
|
|
1410
1410
|
`Duplicate service implementations provided for ${factoryId}`
|
|
1411
1411
|
);
|
|
1412
1412
|
}
|
|
1413
|
-
if (__privateGet$
|
|
1413
|
+
if (__privateGet$7(this, _instantiatedFactories).has(factoryId)) {
|
|
1414
1414
|
throw new Error(
|
|
1415
1415
|
`Unable to set service factory with id ${factoryId}, service has already been instantiated`
|
|
1416
1416
|
);
|
|
1417
1417
|
}
|
|
1418
|
-
__privateGet$
|
|
1419
|
-
__privateGet$
|
|
1418
|
+
__privateGet$7(this, _addedFactoryIds).add(factoryId);
|
|
1419
|
+
__privateGet$7(this, _providedFactories).set(factoryId, toInternalServiceFactory(factory));
|
|
1420
1420
|
}
|
|
1421
1421
|
async initializeEagerServicesWithScope(scope, pluginId = "root") {
|
|
1422
|
-
for (const factory of __privateGet$
|
|
1422
|
+
for (const factory of __privateGet$7(this, _providedFactories).values()) {
|
|
1423
1423
|
if (factory.service.scope === scope) {
|
|
1424
1424
|
if (scope === "root" && factory.initialization !== "lazy") {
|
|
1425
1425
|
await this.get(factory.service, pluginId);
|
|
@@ -1431,12 +1431,12 @@ const _ServiceRegistry = class _ServiceRegistry {
|
|
|
1431
1431
|
}
|
|
1432
1432
|
get(ref, pluginId) {
|
|
1433
1433
|
var _a;
|
|
1434
|
-
__privateGet$
|
|
1435
|
-
return (_a = __privateMethod$
|
|
1434
|
+
__privateGet$7(this, _instantiatedFactories).add(ref.id);
|
|
1435
|
+
return (_a = __privateMethod$6(this, _resolveFactory, resolveFactory_fn).call(this, ref, pluginId)) == null ? void 0 : _a.then((factory) => {
|
|
1436
1436
|
if (factory.service.scope === "root") {
|
|
1437
|
-
let existing = __privateGet$
|
|
1437
|
+
let existing = __privateGet$7(this, _rootServiceImplementations).get(factory);
|
|
1438
1438
|
if (!existing) {
|
|
1439
|
-
__privateMethod$
|
|
1439
|
+
__privateMethod$6(this, _checkForMissingDeps, checkForMissingDeps_fn).call(this, factory, pluginId);
|
|
1440
1440
|
const rootDeps = new Array();
|
|
1441
1441
|
for (const [name, serviceRef] of Object.entries(factory.deps)) {
|
|
1442
1442
|
if (serviceRef.scope !== "root") {
|
|
@@ -1450,13 +1450,13 @@ const _ServiceRegistry = class _ServiceRegistry {
|
|
|
1450
1450
|
existing = Promise.all(rootDeps).then(
|
|
1451
1451
|
(entries) => factory.factory(Object.fromEntries(entries), void 0)
|
|
1452
1452
|
);
|
|
1453
|
-
__privateGet$
|
|
1453
|
+
__privateGet$7(this, _rootServiceImplementations).set(factory, existing);
|
|
1454
1454
|
}
|
|
1455
1455
|
return existing;
|
|
1456
1456
|
}
|
|
1457
|
-
let implementation = __privateGet$
|
|
1457
|
+
let implementation = __privateGet$7(this, _implementations).get(factory);
|
|
1458
1458
|
if (!implementation) {
|
|
1459
|
-
__privateMethod$
|
|
1459
|
+
__privateMethod$6(this, _checkForMissingDeps, checkForMissingDeps_fn).call(this, factory, pluginId);
|
|
1460
1460
|
const rootDeps = new Array();
|
|
1461
1461
|
for (const [name, serviceRef] of Object.entries(factory.deps)) {
|
|
1462
1462
|
if (serviceRef.scope === "root") {
|
|
@@ -1478,7 +1478,7 @@ const _ServiceRegistry = class _ServiceRegistry {
|
|
|
1478
1478
|
}),
|
|
1479
1479
|
byPlugin: /* @__PURE__ */ new Map()
|
|
1480
1480
|
};
|
|
1481
|
-
__privateGet$
|
|
1481
|
+
__privateGet$7(this, _implementations).set(factory, implementation);
|
|
1482
1482
|
}
|
|
1483
1483
|
let result = implementation.byPlugin.get(pluginId);
|
|
1484
1484
|
if (!result) {
|
|
@@ -1516,18 +1516,18 @@ resolveFactory_fn = function(ref, pluginId) {
|
|
|
1516
1516
|
toInternalServiceFactory(pluginMetadataServiceFactory({ pluginId }))
|
|
1517
1517
|
);
|
|
1518
1518
|
}
|
|
1519
|
-
let resolvedFactory = __privateGet$
|
|
1519
|
+
let resolvedFactory = __privateGet$7(this, _providedFactories).get(ref.id);
|
|
1520
1520
|
const { __defaultFactory: defaultFactory } = ref;
|
|
1521
1521
|
if (!resolvedFactory && !defaultFactory) {
|
|
1522
1522
|
return void 0;
|
|
1523
1523
|
}
|
|
1524
1524
|
if (!resolvedFactory) {
|
|
1525
|
-
let loadedFactory = __privateGet$
|
|
1525
|
+
let loadedFactory = __privateGet$7(this, _loadedDefaultFactories).get(defaultFactory);
|
|
1526
1526
|
if (!loadedFactory) {
|
|
1527
1527
|
loadedFactory = Promise.resolve().then(() => defaultFactory(ref)).then(
|
|
1528
1528
|
(f) => toInternalServiceFactory(typeof f === "function" ? f() : f)
|
|
1529
1529
|
);
|
|
1530
|
-
__privateGet$
|
|
1530
|
+
__privateGet$7(this, _loadedDefaultFactories).set(defaultFactory, loadedFactory);
|
|
1531
1531
|
}
|
|
1532
1532
|
resolvedFactory = loadedFactory.catch((error) => {
|
|
1533
1533
|
throw new Error(
|
|
@@ -1545,7 +1545,7 @@ checkForMissingDeps_fn = function(factory, pluginId) {
|
|
|
1545
1545
|
if (ref.id === backendPluginApi.coreServices.pluginMetadata.id) {
|
|
1546
1546
|
return false;
|
|
1547
1547
|
}
|
|
1548
|
-
if (__privateGet$
|
|
1548
|
+
if (__privateGet$7(this, _providedFactories).get(ref.id)) {
|
|
1549
1549
|
return false;
|
|
1550
1550
|
}
|
|
1551
1551
|
return !ref.__defaultFactory;
|
|
@@ -1559,52 +1559,52 @@ checkForMissingDeps_fn = function(factory, pluginId) {
|
|
|
1559
1559
|
};
|
|
1560
1560
|
let ServiceRegistry = _ServiceRegistry;
|
|
1561
1561
|
|
|
1562
|
-
var __accessCheck$
|
|
1562
|
+
var __accessCheck$8 = (obj, member, msg) => {
|
|
1563
1563
|
if (!member.has(obj))
|
|
1564
1564
|
throw TypeError("Cannot " + msg);
|
|
1565
1565
|
};
|
|
1566
|
-
var __privateGet$
|
|
1567
|
-
__accessCheck$
|
|
1566
|
+
var __privateGet$6 = (obj, member, getter) => {
|
|
1567
|
+
__accessCheck$8(obj, member, "read from private field");
|
|
1568
1568
|
return getter ? getter.call(obj) : member.get(obj);
|
|
1569
1569
|
};
|
|
1570
|
-
var __privateAdd$
|
|
1570
|
+
var __privateAdd$8 = (obj, member, value) => {
|
|
1571
1571
|
if (member.has(obj))
|
|
1572
1572
|
throw TypeError("Cannot add the same private member more than once");
|
|
1573
1573
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1574
1574
|
};
|
|
1575
|
-
var __privateSet$
|
|
1576
|
-
__accessCheck$
|
|
1575
|
+
var __privateSet$4 = (obj, member, value, setter) => {
|
|
1576
|
+
__accessCheck$8(obj, member, "write to private field");
|
|
1577
1577
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1578
1578
|
return value;
|
|
1579
1579
|
};
|
|
1580
|
-
var __privateMethod$
|
|
1581
|
-
__accessCheck$
|
|
1580
|
+
var __privateMethod$5 = (obj, member, method) => {
|
|
1581
|
+
__accessCheck$8(obj, member, "access private method");
|
|
1582
1582
|
return method;
|
|
1583
1583
|
};
|
|
1584
1584
|
var _startPromise, _features, _extensionPoints, _serviceRegistry, _registeredFeatures, _getInitDeps, getInitDeps_fn, _addFeature, addFeature_fn, _doStart, doStart_fn, _getRootLifecycleImpl, getRootLifecycleImpl_fn, _getPluginLifecycleImpl, getPluginLifecycleImpl_fn;
|
|
1585
1585
|
class BackendInitializer {
|
|
1586
1586
|
constructor(defaultApiFactories) {
|
|
1587
|
-
__privateAdd$
|
|
1588
|
-
__privateAdd$
|
|
1589
|
-
__privateAdd$
|
|
1587
|
+
__privateAdd$8(this, _getInitDeps);
|
|
1588
|
+
__privateAdd$8(this, _addFeature);
|
|
1589
|
+
__privateAdd$8(this, _doStart);
|
|
1590
1590
|
// Bit of a hacky way to grab the lifecycle services, potentially find a nicer way to do this
|
|
1591
|
-
__privateAdd$
|
|
1592
|
-
__privateAdd$
|
|
1593
|
-
__privateAdd$
|
|
1594
|
-
__privateAdd$
|
|
1595
|
-
__privateAdd$
|
|
1596
|
-
__privateAdd$
|
|
1597
|
-
__privateAdd$
|
|
1598
|
-
__privateSet$
|
|
1591
|
+
__privateAdd$8(this, _getRootLifecycleImpl);
|
|
1592
|
+
__privateAdd$8(this, _getPluginLifecycleImpl);
|
|
1593
|
+
__privateAdd$8(this, _startPromise, void 0);
|
|
1594
|
+
__privateAdd$8(this, _features, new Array());
|
|
1595
|
+
__privateAdd$8(this, _extensionPoints, /* @__PURE__ */ new Map());
|
|
1596
|
+
__privateAdd$8(this, _serviceRegistry, void 0);
|
|
1597
|
+
__privateAdd$8(this, _registeredFeatures, new Array());
|
|
1598
|
+
__privateSet$4(this, _serviceRegistry, ServiceRegistry.create([...defaultApiFactories]));
|
|
1599
1599
|
}
|
|
1600
1600
|
add(feature) {
|
|
1601
|
-
if (__privateGet$
|
|
1601
|
+
if (__privateGet$6(this, _startPromise)) {
|
|
1602
1602
|
throw new Error("feature can not be added after the backend has started");
|
|
1603
1603
|
}
|
|
1604
|
-
__privateGet$
|
|
1604
|
+
__privateGet$6(this, _registeredFeatures).push(Promise.resolve(feature));
|
|
1605
1605
|
}
|
|
1606
1606
|
async start() {
|
|
1607
|
-
if (__privateGet$
|
|
1607
|
+
if (__privateGet$6(this, _startPromise)) {
|
|
1608
1608
|
throw new Error("Backend has already started");
|
|
1609
1609
|
}
|
|
1610
1610
|
const exitHandler = async () => {
|
|
@@ -1622,18 +1622,18 @@ class BackendInitializer {
|
|
|
1622
1622
|
process.addListener("SIGTERM", exitHandler);
|
|
1623
1623
|
process.addListener("SIGINT", exitHandler);
|
|
1624
1624
|
process.addListener("beforeExit", exitHandler);
|
|
1625
|
-
__privateSet$
|
|
1626
|
-
await __privateGet$
|
|
1625
|
+
__privateSet$4(this, _startPromise, __privateMethod$5(this, _doStart, doStart_fn).call(this));
|
|
1626
|
+
await __privateGet$6(this, _startPromise);
|
|
1627
1627
|
}
|
|
1628
1628
|
async stop() {
|
|
1629
|
-
if (!__privateGet$
|
|
1629
|
+
if (!__privateGet$6(this, _startPromise)) {
|
|
1630
1630
|
return;
|
|
1631
1631
|
}
|
|
1632
1632
|
try {
|
|
1633
|
-
await __privateGet$
|
|
1633
|
+
await __privateGet$6(this, _startPromise);
|
|
1634
1634
|
} catch (error) {
|
|
1635
1635
|
}
|
|
1636
|
-
const lifecycleService = await __privateMethod$
|
|
1636
|
+
const lifecycleService = await __privateMethod$5(this, _getRootLifecycleImpl, getRootLifecycleImpl_fn).call(this);
|
|
1637
1637
|
await lifecycleService.shutdown();
|
|
1638
1638
|
}
|
|
1639
1639
|
}
|
|
@@ -1647,7 +1647,7 @@ getInitDeps_fn = async function(deps, pluginId, moduleId) {
|
|
|
1647
1647
|
const result = /* @__PURE__ */ new Map();
|
|
1648
1648
|
const missingRefs = /* @__PURE__ */ new Set();
|
|
1649
1649
|
for (const [name, ref] of Object.entries(deps)) {
|
|
1650
|
-
const ep = __privateGet$
|
|
1650
|
+
const ep = __privateGet$6(this, _extensionPoints).get(ref.id);
|
|
1651
1651
|
if (ep) {
|
|
1652
1652
|
if (ep.pluginId !== pluginId) {
|
|
1653
1653
|
throw new Error(
|
|
@@ -1656,7 +1656,7 @@ getInitDeps_fn = async function(deps, pluginId, moduleId) {
|
|
|
1656
1656
|
}
|
|
1657
1657
|
result.set(name, ep.impl);
|
|
1658
1658
|
} else {
|
|
1659
|
-
const impl = await __privateGet$
|
|
1659
|
+
const impl = await __privateGet$6(this, _serviceRegistry).get(
|
|
1660
1660
|
ref,
|
|
1661
1661
|
pluginId
|
|
1662
1662
|
);
|
|
@@ -1683,14 +1683,14 @@ addFeature_fn = function(feature) {
|
|
|
1683
1683
|
);
|
|
1684
1684
|
}
|
|
1685
1685
|
if (isServiceFactory(feature)) {
|
|
1686
|
-
__privateGet$
|
|
1686
|
+
__privateGet$6(this, _serviceRegistry).add(feature);
|
|
1687
1687
|
} else if (isInternalBackendFeature(feature)) {
|
|
1688
1688
|
if (feature.version !== "v1") {
|
|
1689
1689
|
throw new Error(
|
|
1690
1690
|
`Failed to add feature, invalid version '${feature.version}'`
|
|
1691
1691
|
);
|
|
1692
1692
|
}
|
|
1693
|
-
__privateGet$
|
|
1693
|
+
__privateGet$6(this, _features).push(feature);
|
|
1694
1694
|
} else {
|
|
1695
1695
|
throw new Error(
|
|
1696
1696
|
`Failed to add feature, invalid feature ${JSON.stringify(feature)}`
|
|
@@ -1699,35 +1699,35 @@ addFeature_fn = function(feature) {
|
|
|
1699
1699
|
};
|
|
1700
1700
|
_doStart = new WeakSet();
|
|
1701
1701
|
doStart_fn = async function() {
|
|
1702
|
-
__privateGet$
|
|
1703
|
-
for (const feature of __privateGet$
|
|
1704
|
-
__privateMethod$
|
|
1702
|
+
__privateGet$6(this, _serviceRegistry).checkForCircularDeps();
|
|
1703
|
+
for (const feature of __privateGet$6(this, _registeredFeatures)) {
|
|
1704
|
+
__privateMethod$5(this, _addFeature, addFeature_fn).call(this, await feature);
|
|
1705
1705
|
}
|
|
1706
|
-
const featureDiscovery = await __privateGet$
|
|
1706
|
+
const featureDiscovery = await __privateGet$6(this, _serviceRegistry).get(
|
|
1707
1707
|
alpha.featureDiscoveryServiceRef,
|
|
1708
1708
|
"root"
|
|
1709
1709
|
);
|
|
1710
1710
|
if (featureDiscovery) {
|
|
1711
1711
|
const { features } = await featureDiscovery.getBackendFeatures();
|
|
1712
1712
|
for (const feature of features) {
|
|
1713
|
-
__privateMethod$
|
|
1713
|
+
__privateMethod$5(this, _addFeature, addFeature_fn).call(this, feature);
|
|
1714
1714
|
}
|
|
1715
|
-
__privateGet$
|
|
1715
|
+
__privateGet$6(this, _serviceRegistry).checkForCircularDeps();
|
|
1716
1716
|
}
|
|
1717
|
-
await __privateGet$
|
|
1717
|
+
await __privateGet$6(this, _serviceRegistry).initializeEagerServicesWithScope("root");
|
|
1718
1718
|
const pluginInits = /* @__PURE__ */ new Map();
|
|
1719
1719
|
const moduleInits = /* @__PURE__ */ new Map();
|
|
1720
|
-
for (const feature of __privateGet$
|
|
1720
|
+
for (const feature of __privateGet$6(this, _features)) {
|
|
1721
1721
|
for (const r of feature.getRegistrations()) {
|
|
1722
1722
|
const provides = /* @__PURE__ */ new Set();
|
|
1723
1723
|
if (r.type === "plugin" || r.type === "module") {
|
|
1724
1724
|
for (const [extRef, extImpl] of r.extensionPoints) {
|
|
1725
|
-
if (__privateGet$
|
|
1725
|
+
if (__privateGet$6(this, _extensionPoints).has(extRef.id)) {
|
|
1726
1726
|
throw new Error(
|
|
1727
1727
|
`ExtensionPoint with ID '${extRef.id}' is already registered`
|
|
1728
1728
|
);
|
|
1729
1729
|
}
|
|
1730
|
-
__privateGet$
|
|
1730
|
+
__privateGet$6(this, _extensionPoints).set(extRef.id, {
|
|
1731
1731
|
impl: extImpl,
|
|
1732
1732
|
pluginId: r.pluginId
|
|
1733
1733
|
});
|
|
@@ -1765,7 +1765,7 @@ doStart_fn = async function() {
|
|
|
1765
1765
|
const allPluginIds = [...pluginInits.keys()];
|
|
1766
1766
|
await Promise.all(
|
|
1767
1767
|
allPluginIds.map(async (pluginId) => {
|
|
1768
|
-
await __privateGet$
|
|
1768
|
+
await __privateGet$6(this, _serviceRegistry).initializeEagerServicesWithScope(
|
|
1769
1769
|
"plugin",
|
|
1770
1770
|
pluginId
|
|
1771
1771
|
);
|
|
@@ -1789,7 +1789,7 @@ doStart_fn = async function() {
|
|
|
1789
1789
|
}
|
|
1790
1790
|
await tree.parallelTopologicalTraversal(
|
|
1791
1791
|
async ({ moduleId, moduleInit }) => {
|
|
1792
|
-
const moduleDeps = await __privateMethod$
|
|
1792
|
+
const moduleDeps = await __privateMethod$5(this, _getInitDeps, getInitDeps_fn).call(this, moduleInit.init.deps, pluginId, moduleId);
|
|
1793
1793
|
await moduleInit.init.func(moduleDeps).catch((error) => {
|
|
1794
1794
|
throw new errors.ForwardedError(
|
|
1795
1795
|
`Module '${moduleId}' for plugin '${pluginId}' startup failed`,
|
|
@@ -1801,7 +1801,7 @@ doStart_fn = async function() {
|
|
|
1801
1801
|
}
|
|
1802
1802
|
const pluginInit = pluginInits.get(pluginId);
|
|
1803
1803
|
if (pluginInit) {
|
|
1804
|
-
const pluginDeps = await __privateMethod$
|
|
1804
|
+
const pluginDeps = await __privateMethod$5(this, _getInitDeps, getInitDeps_fn).call(this, pluginInit.init.deps, pluginId);
|
|
1805
1805
|
await pluginInit.init.func(pluginDeps).catch((error) => {
|
|
1806
1806
|
throw new errors.ForwardedError(
|
|
1807
1807
|
`Plugin '${pluginId}' startup failed`,
|
|
@@ -1809,14 +1809,14 @@ doStart_fn = async function() {
|
|
|
1809
1809
|
);
|
|
1810
1810
|
});
|
|
1811
1811
|
}
|
|
1812
|
-
const lifecycleService2 = await __privateMethod$
|
|
1812
|
+
const lifecycleService2 = await __privateMethod$5(this, _getPluginLifecycleImpl, getPluginLifecycleImpl_fn).call(this, pluginId);
|
|
1813
1813
|
await lifecycleService2.startup();
|
|
1814
1814
|
})
|
|
1815
1815
|
);
|
|
1816
|
-
const lifecycleService = await __privateMethod$
|
|
1816
|
+
const lifecycleService = await __privateMethod$5(this, _getRootLifecycleImpl, getRootLifecycleImpl_fn).call(this);
|
|
1817
1817
|
await lifecycleService.startup();
|
|
1818
1818
|
if (process.env.NODE_ENV !== "test") {
|
|
1819
|
-
const rootLogger = await __privateGet$
|
|
1819
|
+
const rootLogger = await __privateGet$6(this, _serviceRegistry).get(
|
|
1820
1820
|
backendPluginApi.coreServices.rootLogger,
|
|
1821
1821
|
"root"
|
|
1822
1822
|
);
|
|
@@ -1832,7 +1832,7 @@ doStart_fn = async function() {
|
|
|
1832
1832
|
};
|
|
1833
1833
|
_getRootLifecycleImpl = new WeakSet();
|
|
1834
1834
|
getRootLifecycleImpl_fn = async function() {
|
|
1835
|
-
const lifecycleService = await __privateGet$
|
|
1835
|
+
const lifecycleService = await __privateGet$6(this, _serviceRegistry).get(
|
|
1836
1836
|
backendPluginApi.coreServices.rootLifecycle,
|
|
1837
1837
|
"root"
|
|
1838
1838
|
);
|
|
@@ -1843,7 +1843,7 @@ getRootLifecycleImpl_fn = async function() {
|
|
|
1843
1843
|
};
|
|
1844
1844
|
_getPluginLifecycleImpl = new WeakSet();
|
|
1845
1845
|
getPluginLifecycleImpl_fn = async function(pluginId) {
|
|
1846
|
-
const lifecycleService = await __privateGet$
|
|
1846
|
+
const lifecycleService = await __privateGet$6(this, _serviceRegistry).get(
|
|
1847
1847
|
backendPluginApi.coreServices.lifecycle,
|
|
1848
1848
|
pluginId
|
|
1849
1849
|
);
|
|
@@ -1859,42 +1859,42 @@ function isInternalBackendFeature(feature) {
|
|
|
1859
1859
|
return typeof feature.getRegistrations === "function";
|
|
1860
1860
|
}
|
|
1861
1861
|
|
|
1862
|
-
var __accessCheck$
|
|
1862
|
+
var __accessCheck$7 = (obj, member, msg) => {
|
|
1863
1863
|
if (!member.has(obj))
|
|
1864
1864
|
throw TypeError("Cannot " + msg);
|
|
1865
1865
|
};
|
|
1866
|
-
var __privateGet$
|
|
1867
|
-
__accessCheck$
|
|
1866
|
+
var __privateGet$5 = (obj, member, getter) => {
|
|
1867
|
+
__accessCheck$7(obj, member, "read from private field");
|
|
1868
1868
|
return getter ? getter.call(obj) : member.get(obj);
|
|
1869
1869
|
};
|
|
1870
|
-
var __privateAdd$
|
|
1870
|
+
var __privateAdd$7 = (obj, member, value) => {
|
|
1871
1871
|
if (member.has(obj))
|
|
1872
1872
|
throw TypeError("Cannot add the same private member more than once");
|
|
1873
1873
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
1874
1874
|
};
|
|
1875
|
-
var __privateSet$
|
|
1876
|
-
__accessCheck$
|
|
1875
|
+
var __privateSet$3 = (obj, member, value, setter) => {
|
|
1876
|
+
__accessCheck$7(obj, member, "write to private field");
|
|
1877
1877
|
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
1878
1878
|
return value;
|
|
1879
1879
|
};
|
|
1880
1880
|
var _initializer;
|
|
1881
1881
|
class BackstageBackend {
|
|
1882
1882
|
constructor(defaultServiceFactories) {
|
|
1883
|
-
__privateAdd$
|
|
1884
|
-
__privateSet$
|
|
1883
|
+
__privateAdd$7(this, _initializer, void 0);
|
|
1884
|
+
__privateSet$3(this, _initializer, new BackendInitializer(defaultServiceFactories));
|
|
1885
1885
|
}
|
|
1886
1886
|
add(feature) {
|
|
1887
1887
|
if (isPromise(feature)) {
|
|
1888
|
-
__privateGet$
|
|
1888
|
+
__privateGet$5(this, _initializer).add(feature.then((f) => unwrapFeature(f.default)));
|
|
1889
1889
|
} else {
|
|
1890
|
-
__privateGet$
|
|
1890
|
+
__privateGet$5(this, _initializer).add(unwrapFeature(feature));
|
|
1891
1891
|
}
|
|
1892
1892
|
}
|
|
1893
1893
|
async start() {
|
|
1894
|
-
await __privateGet$
|
|
1894
|
+
await __privateGet$5(this, _initializer).start();
|
|
1895
1895
|
}
|
|
1896
1896
|
async stop() {
|
|
1897
|
-
await __privateGet$
|
|
1897
|
+
await __privateGet$5(this, _initializer).stop();
|
|
1898
1898
|
}
|
|
1899
1899
|
}
|
|
1900
1900
|
_initializer = new WeakMap();
|
|
@@ -1940,199 +1940,322 @@ function createSpecializedBackend(options) {
|
|
|
1940
1940
|
return new BackstageBackend(services);
|
|
1941
1941
|
}
|
|
1942
1942
|
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
return value;
|
|
1960
|
-
};
|
|
1961
|
-
var _keyStore, _keyStoreUpdated;
|
|
1962
|
-
const CLOCK_MARGIN_S = 10;
|
|
1963
|
-
class JwksClient {
|
|
1964
|
-
constructor(getEndpoint) {
|
|
1965
|
-
this.getEndpoint = getEndpoint;
|
|
1966
|
-
__privateAdd$4(this, _keyStore, void 0);
|
|
1967
|
-
__privateAdd$4(this, _keyStoreUpdated, 0);
|
|
1943
|
+
const MIGRATIONS_TABLE = "backstage_backend_public_keys__knex_migrations";
|
|
1944
|
+
const TABLE = "backstage_backend_public_keys__keys";
|
|
1945
|
+
function applyDatabaseMigrations(knex) {
|
|
1946
|
+
const migrationsDir = backendCommon.resolvePackagePath(
|
|
1947
|
+
"@backstage/backend-app-api",
|
|
1948
|
+
"migrations"
|
|
1949
|
+
);
|
|
1950
|
+
return knex.migrate.latest({
|
|
1951
|
+
directory: migrationsDir,
|
|
1952
|
+
tableName: MIGRATIONS_TABLE
|
|
1953
|
+
});
|
|
1954
|
+
}
|
|
1955
|
+
class DatabaseKeyStore {
|
|
1956
|
+
constructor(client, logger) {
|
|
1957
|
+
this.client = client;
|
|
1958
|
+
this.logger = logger;
|
|
1968
1959
|
}
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1960
|
+
static async create(options) {
|
|
1961
|
+
var _a;
|
|
1962
|
+
const { database, logger } = options;
|
|
1963
|
+
const client = await database.getClient();
|
|
1964
|
+
if (!((_a = database.migrations) == null ? void 0 : _a.skip)) {
|
|
1965
|
+
await applyDatabaseMigrations(client);
|
|
1974
1966
|
}
|
|
1975
|
-
return
|
|
1967
|
+
return new DatabaseKeyStore(client, logger);
|
|
1976
1968
|
}
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1969
|
+
async addKey(options) {
|
|
1970
|
+
await this.client(TABLE).insert({
|
|
1971
|
+
id: options.key.kid,
|
|
1972
|
+
key: JSON.stringify(options.key),
|
|
1973
|
+
expires_at: options.expiresAt.toISOString()
|
|
1974
|
+
});
|
|
1975
|
+
}
|
|
1976
|
+
async listKeys() {
|
|
1977
|
+
const rows = await this.client(TABLE).select();
|
|
1978
|
+
const keys = rows.map((row) => ({
|
|
1979
|
+
id: row.id,
|
|
1980
|
+
key: JSON.parse(row.key),
|
|
1981
|
+
expiresAt: new Date(row.expires_at)
|
|
1982
|
+
}));
|
|
1983
|
+
const validKeys = [];
|
|
1984
|
+
const expiredKeys = [];
|
|
1985
|
+
for (const key of keys) {
|
|
1986
|
+
if (luxon.DateTime.fromJSDate(key.expiresAt) < luxon.DateTime.local()) {
|
|
1987
|
+
expiredKeys.push(key);
|
|
1988
|
+
} else {
|
|
1989
|
+
validKeys.push(key);
|
|
1991
1990
|
}
|
|
1992
|
-
} catch (error) {
|
|
1993
|
-
keyStoreHasKey = false;
|
|
1994
1991
|
}
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
1992
|
+
if (expiredKeys.length > 0) {
|
|
1993
|
+
const kids = expiredKeys.map(({ key }) => key.kid);
|
|
1994
|
+
this.logger.info(
|
|
1995
|
+
`Removing expired plugin service keys, '${kids.join("', '")}'`
|
|
1996
|
+
);
|
|
1997
|
+
this.client(TABLE).delete().whereIn("id", kids).catch((error) => {
|
|
1998
|
+
this.logger.error(
|
|
1999
|
+
"Failed to remove expired plugin service keys",
|
|
2000
|
+
error
|
|
2001
|
+
);
|
|
2002
|
+
});
|
|
2000
2003
|
}
|
|
2004
|
+
return { keys: validKeys };
|
|
2001
2005
|
}
|
|
2002
2006
|
}
|
|
2003
|
-
_keyStore = new WeakMap();
|
|
2004
|
-
_keyStoreUpdated = new WeakMap();
|
|
2005
2007
|
|
|
2006
|
-
|
|
2008
|
+
function createCredentialsWithServicePrincipal(sub, token) {
|
|
2009
|
+
return {
|
|
2010
|
+
$$type: "@backstage/BackstageCredentials",
|
|
2011
|
+
version: "v1",
|
|
2012
|
+
token,
|
|
2013
|
+
principal: {
|
|
2014
|
+
type: "service",
|
|
2015
|
+
subject: sub
|
|
2016
|
+
}
|
|
2017
|
+
};
|
|
2018
|
+
}
|
|
2019
|
+
function createCredentialsWithUserPrincipal(sub, token, expiresAt) {
|
|
2020
|
+
return {
|
|
2021
|
+
$$type: "@backstage/BackstageCredentials",
|
|
2022
|
+
version: "v1",
|
|
2023
|
+
token,
|
|
2024
|
+
expiresAt,
|
|
2025
|
+
principal: {
|
|
2026
|
+
type: "user",
|
|
2027
|
+
userEntityRef: sub
|
|
2028
|
+
}
|
|
2029
|
+
};
|
|
2030
|
+
}
|
|
2031
|
+
function createCredentialsWithNonePrincipal() {
|
|
2032
|
+
return {
|
|
2033
|
+
$$type: "@backstage/BackstageCredentials",
|
|
2034
|
+
version: "v1",
|
|
2035
|
+
principal: {
|
|
2036
|
+
type: "none"
|
|
2037
|
+
}
|
|
2038
|
+
};
|
|
2039
|
+
}
|
|
2040
|
+
function toInternalBackstageCredentials(credentials) {
|
|
2041
|
+
if (credentials.$$type !== "@backstage/BackstageCredentials") {
|
|
2042
|
+
throw new Error("Invalid credential type");
|
|
2043
|
+
}
|
|
2044
|
+
const internalCredentials = credentials;
|
|
2045
|
+
if (internalCredentials.version !== "v1") {
|
|
2046
|
+
throw new Error(
|
|
2047
|
+
`Invalid credential version ${internalCredentials.version}`
|
|
2048
|
+
);
|
|
2049
|
+
}
|
|
2050
|
+
return internalCredentials;
|
|
2051
|
+
}
|
|
2052
|
+
|
|
2053
|
+
var __accessCheck$6 = (obj, member, msg) => {
|
|
2007
2054
|
if (!member.has(obj))
|
|
2008
2055
|
throw TypeError("Cannot " + msg);
|
|
2009
2056
|
};
|
|
2010
|
-
var
|
|
2011
|
-
__accessCheck$3(obj, member, "read from private field");
|
|
2012
|
-
return getter ? getter.call(obj) : member.get(obj);
|
|
2013
|
-
};
|
|
2014
|
-
var __privateAdd$3 = (obj, member, value) => {
|
|
2057
|
+
var __privateAdd$6 = (obj, member, value) => {
|
|
2015
2058
|
if (member.has(obj))
|
|
2016
2059
|
throw TypeError("Cannot add the same private member more than once");
|
|
2017
2060
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
2018
2061
|
};
|
|
2019
|
-
var
|
|
2020
|
-
__accessCheck$
|
|
2021
|
-
|
|
2022
|
-
return value;
|
|
2062
|
+
var __privateMethod$4 = (obj, member, method) => {
|
|
2063
|
+
__accessCheck$6(obj, member, "access private method");
|
|
2064
|
+
return method;
|
|
2023
2065
|
};
|
|
2024
|
-
var
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
__privateSet$2(this, _jwksClient, new JwksClient(async () => {
|
|
2036
|
-
const url = await options.discovery.getBaseUrl("auth");
|
|
2037
|
-
return new URL(`${url}/.well-known/jwks.json`);
|
|
2038
|
-
}));
|
|
2066
|
+
var _getJwtExpiration, getJwtExpiration_fn;
|
|
2067
|
+
class DefaultAuthService {
|
|
2068
|
+
constructor(userTokenHandler, pluginTokenHandler, externalTokenHandler, tokenManager, pluginId, disableDefaultAuthPolicy, publicKeyStore) {
|
|
2069
|
+
this.userTokenHandler = userTokenHandler;
|
|
2070
|
+
this.pluginTokenHandler = pluginTokenHandler;
|
|
2071
|
+
this.externalTokenHandler = externalTokenHandler;
|
|
2072
|
+
this.tokenManager = tokenManager;
|
|
2073
|
+
this.pluginId = pluginId;
|
|
2074
|
+
this.disableDefaultAuthPolicy = disableDefaultAuthPolicy;
|
|
2075
|
+
this.publicKeyStore = publicKeyStore;
|
|
2076
|
+
__privateAdd$6(this, _getJwtExpiration);
|
|
2039
2077
|
}
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2078
|
+
// allowLimitedAccess is currently ignored, since we currently always use the full user tokens
|
|
2079
|
+
async authenticate(token) {
|
|
2080
|
+
const pluginResult = await this.pluginTokenHandler.verifyToken(token);
|
|
2081
|
+
if (pluginResult) {
|
|
2082
|
+
if (pluginResult.limitedUserToken) {
|
|
2083
|
+
const userResult2 = await this.userTokenHandler.verifyToken(
|
|
2084
|
+
pluginResult.limitedUserToken
|
|
2085
|
+
);
|
|
2086
|
+
if (!userResult2) {
|
|
2087
|
+
throw new errors.AuthenticationError(
|
|
2088
|
+
"Invalid user token in plugin token obo claim"
|
|
2089
|
+
);
|
|
2090
|
+
}
|
|
2091
|
+
return createCredentialsWithUserPrincipal(
|
|
2092
|
+
userResult2.userEntityRef,
|
|
2093
|
+
pluginResult.limitedUserToken,
|
|
2094
|
+
__privateMethod$4(this, _getJwtExpiration, getJwtExpiration_fn).call(this, pluginResult.limitedUserToken)
|
|
2095
|
+
);
|
|
2096
|
+
}
|
|
2097
|
+
return createCredentialsWithServicePrincipal(pluginResult.subject);
|
|
2044
2098
|
}
|
|
2045
|
-
await
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
});
|
|
2053
|
-
const userEntityRef = payload.sub;
|
|
2054
|
-
if (!userEntityRef) {
|
|
2055
|
-
throw new errors.AuthenticationError("No user sub found in token");
|
|
2099
|
+
const userResult = await this.userTokenHandler.verifyToken(token);
|
|
2100
|
+
if (userResult) {
|
|
2101
|
+
return createCredentialsWithUserPrincipal(
|
|
2102
|
+
userResult.userEntityRef,
|
|
2103
|
+
token,
|
|
2104
|
+
__privateMethod$4(this, _getJwtExpiration, getJwtExpiration_fn).call(this, token)
|
|
2105
|
+
);
|
|
2056
2106
|
}
|
|
2057
|
-
|
|
2107
|
+
const externalResult = await this.externalTokenHandler.verifyToken(token);
|
|
2108
|
+
if (externalResult) {
|
|
2109
|
+
return createCredentialsWithServicePrincipal(externalResult.subject);
|
|
2110
|
+
}
|
|
2111
|
+
throw new errors.AuthenticationError("Illegal token");
|
|
2058
2112
|
}
|
|
2059
|
-
|
|
2060
|
-
const
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
);
|
|
2064
|
-
const payload = JSON.parse(
|
|
2065
|
-
new TextDecoder().decode(jose.base64url.decode(payloadRaw))
|
|
2066
|
-
);
|
|
2067
|
-
const tokenType = header.typ;
|
|
2068
|
-
if (!tokenType || tokenType === pluginAuthNode.tokenTypes.limitedUser.typParam) {
|
|
2069
|
-
return { token: backstageToken, expiresAt: new Date(payload.exp * 1e3) };
|
|
2113
|
+
isPrincipal(credentials, type) {
|
|
2114
|
+
const principal = credentials.principal;
|
|
2115
|
+
if (type === "unknown") {
|
|
2116
|
+
return true;
|
|
2070
2117
|
}
|
|
2071
|
-
if (
|
|
2118
|
+
if (principal.type !== type) {
|
|
2119
|
+
return false;
|
|
2120
|
+
}
|
|
2121
|
+
return true;
|
|
2122
|
+
}
|
|
2123
|
+
async getNoneCredentials() {
|
|
2124
|
+
return createCredentialsWithNonePrincipal();
|
|
2125
|
+
}
|
|
2126
|
+
async getOwnServiceCredentials() {
|
|
2127
|
+
return createCredentialsWithServicePrincipal(`plugin:${this.pluginId}`);
|
|
2128
|
+
}
|
|
2129
|
+
async getPluginRequestToken(options) {
|
|
2130
|
+
const { targetPluginId } = options;
|
|
2131
|
+
const internalForward = toInternalBackstageCredentials(options.onBehalfOf);
|
|
2132
|
+
const { type } = internalForward.principal;
|
|
2133
|
+
if (type === "none" && this.disableDefaultAuthPolicy) {
|
|
2134
|
+
return { token: "" };
|
|
2135
|
+
}
|
|
2136
|
+
const targetSupportsNewAuth = await this.pluginTokenHandler.isTargetPluginSupported(targetPluginId);
|
|
2137
|
+
switch (type) {
|
|
2138
|
+
case "service":
|
|
2139
|
+
if (targetSupportsNewAuth) {
|
|
2140
|
+
return this.pluginTokenHandler.issueToken({
|
|
2141
|
+
pluginId: this.pluginId,
|
|
2142
|
+
targetPluginId
|
|
2143
|
+
});
|
|
2144
|
+
}
|
|
2145
|
+
return this.tokenManager.getToken();
|
|
2146
|
+
case "user": {
|
|
2147
|
+
const { token } = internalForward;
|
|
2148
|
+
if (!token) {
|
|
2149
|
+
throw new Error("User credentials is unexpectedly missing token");
|
|
2150
|
+
}
|
|
2151
|
+
if (targetSupportsNewAuth) {
|
|
2152
|
+
const onBehalfOf = await this.userTokenHandler.createLimitedUserToken(
|
|
2153
|
+
token
|
|
2154
|
+
);
|
|
2155
|
+
return this.pluginTokenHandler.issueToken({
|
|
2156
|
+
pluginId: this.pluginId,
|
|
2157
|
+
targetPluginId,
|
|
2158
|
+
onBehalfOf
|
|
2159
|
+
});
|
|
2160
|
+
}
|
|
2161
|
+
if (this.userTokenHandler.isLimitedUserToken(token)) {
|
|
2162
|
+
throw new errors.AuthenticationError(
|
|
2163
|
+
`Unable to call '${targetPluginId}' plugin on behalf of user, because the target plugin does not support on-behalf-of tokens or the plugin doesn't exist`
|
|
2164
|
+
);
|
|
2165
|
+
}
|
|
2166
|
+
return { token };
|
|
2167
|
+
}
|
|
2168
|
+
default:
|
|
2169
|
+
throw new errors.AuthenticationError(
|
|
2170
|
+
`Refused to issue service token for credential type '${type}'`
|
|
2171
|
+
);
|
|
2172
|
+
}
|
|
2173
|
+
}
|
|
2174
|
+
async getLimitedUserToken(credentials) {
|
|
2175
|
+
const { token: backstageToken } = toInternalBackstageCredentials(credentials);
|
|
2176
|
+
if (!backstageToken) {
|
|
2072
2177
|
throw new errors.AuthenticationError(
|
|
2073
|
-
"
|
|
2178
|
+
"User credentials is unexpectedly missing token"
|
|
2074
2179
|
);
|
|
2075
2180
|
}
|
|
2076
|
-
|
|
2077
|
-
jose.base64url.encode(
|
|
2078
|
-
JSON.stringify({
|
|
2079
|
-
typ: pluginAuthNode.tokenTypes.limitedUser.typParam,
|
|
2080
|
-
alg: header.alg,
|
|
2081
|
-
kid: header.kid
|
|
2082
|
-
})
|
|
2083
|
-
),
|
|
2084
|
-
jose.base64url.encode(
|
|
2085
|
-
JSON.stringify({
|
|
2086
|
-
sub: payload.sub,
|
|
2087
|
-
ent: payload.ent,
|
|
2088
|
-
iat: payload.iat,
|
|
2089
|
-
exp: payload.exp
|
|
2090
|
-
})
|
|
2091
|
-
),
|
|
2092
|
-
payload.uip
|
|
2093
|
-
].join(".");
|
|
2094
|
-
return { token: limitedUserToken, expiresAt: new Date(payload.exp * 1e3) };
|
|
2181
|
+
return this.userTokenHandler.createLimitedUserToken(backstageToken);
|
|
2095
2182
|
}
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
return typ === pluginAuthNode.tokenTypes.limitedUser.typParam;
|
|
2100
|
-
} catch {
|
|
2101
|
-
return false;
|
|
2102
|
-
}
|
|
2183
|
+
async listPublicServiceKeys() {
|
|
2184
|
+
const { keys } = await this.publicKeyStore.listKeys();
|
|
2185
|
+
return { keys: keys.map(({ key }) => key) };
|
|
2103
2186
|
}
|
|
2104
2187
|
}
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2188
|
+
_getJwtExpiration = new WeakSet();
|
|
2189
|
+
getJwtExpiration_fn = function(token) {
|
|
2190
|
+
const { exp } = jose.decodeJwt(token);
|
|
2191
|
+
if (!exp) {
|
|
2192
|
+
throw new errors.AuthenticationError("User token is missing expiration");
|
|
2193
|
+
}
|
|
2194
|
+
return new Date(exp * 1e3);
|
|
2195
|
+
};
|
|
2196
|
+
|
|
2197
|
+
var __accessCheck$5 = (obj, member, msg) => {
|
|
2198
|
+
if (!member.has(obj))
|
|
2199
|
+
throw TypeError("Cannot " + msg);
|
|
2200
|
+
};
|
|
2201
|
+
var __privateGet$4 = (obj, member, getter) => {
|
|
2202
|
+
__accessCheck$5(obj, member, "read from private field");
|
|
2203
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
2204
|
+
};
|
|
2205
|
+
var __privateAdd$5 = (obj, member, value) => {
|
|
2206
|
+
if (member.has(obj))
|
|
2207
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
2208
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
2209
|
+
};
|
|
2210
|
+
var __privateSet$2 = (obj, member, value, setter) => {
|
|
2211
|
+
__accessCheck$5(obj, member, "write to private field");
|
|
2212
|
+
setter ? setter.call(obj, value) : member.set(obj, value);
|
|
2213
|
+
return value;
|
|
2214
|
+
};
|
|
2215
|
+
var _keyStore, _keyStoreUpdated;
|
|
2216
|
+
const CLOCK_MARGIN_S = 10;
|
|
2217
|
+
class JwksClient {
|
|
2218
|
+
constructor(getEndpoint) {
|
|
2219
|
+
this.getEndpoint = getEndpoint;
|
|
2220
|
+
__privateAdd$5(this, _keyStore, void 0);
|
|
2221
|
+
__privateAdd$5(this, _keyStoreUpdated, 0);
|
|
2222
|
+
}
|
|
2223
|
+
get getKey() {
|
|
2224
|
+
if (!__privateGet$4(this, _keyStore)) {
|
|
2225
|
+
throw new errors.AuthenticationError(
|
|
2226
|
+
"refreshKeyStore must be called before jwksClient.getKey"
|
|
2227
|
+
);
|
|
2117
2228
|
}
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2229
|
+
return __privateGet$4(this, _keyStore);
|
|
2230
|
+
}
|
|
2231
|
+
/**
|
|
2232
|
+
* If the last keystore refresh is stale, update the keystore URL to the latest
|
|
2233
|
+
*/
|
|
2234
|
+
async refreshKeyStore(rawJwtToken) {
|
|
2235
|
+
const payload = await jose.decodeJwt(rawJwtToken);
|
|
2236
|
+
const header = await jose.decodeProtectedHeader(rawJwtToken);
|
|
2237
|
+
let keyStoreHasKey;
|
|
2238
|
+
try {
|
|
2239
|
+
if (__privateGet$4(this, _keyStore)) {
|
|
2240
|
+
const [_, rawPayload, rawSignature] = rawJwtToken.split(".");
|
|
2241
|
+
keyStoreHasKey = await __privateGet$4(this, _keyStore).call(this, header, {
|
|
2242
|
+
payload: rawPayload,
|
|
2243
|
+
signature: rawSignature
|
|
2244
|
+
});
|
|
2245
|
+
}
|
|
2246
|
+
} catch (error) {
|
|
2247
|
+
keyStoreHasKey = false;
|
|
2124
2248
|
}
|
|
2125
|
-
const
|
|
2126
|
-
if (
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
};
|
|
2249
|
+
const issuedAfterLastRefresh = (payload == null ? void 0 : payload.iat) && payload.iat > __privateGet$4(this, _keyStoreUpdated) - CLOCK_MARGIN_S;
|
|
2250
|
+
if (!__privateGet$4(this, _keyStore) || !keyStoreHasKey && issuedAfterLastRefresh) {
|
|
2251
|
+
const endpoint = await this.getEndpoint();
|
|
2252
|
+
__privateSet$2(this, _keyStore, jose.createRemoteJWKSet(endpoint));
|
|
2253
|
+
__privateSet$2(this, _keyStoreUpdated, Date.now() / 1e3);
|
|
2131
2254
|
}
|
|
2132
|
-
} catch {
|
|
2133
2255
|
}
|
|
2134
|
-
|
|
2135
|
-
|
|
2256
|
+
}
|
|
2257
|
+
_keyStore = new WeakMap();
|
|
2258
|
+
_keyStoreUpdated = new WeakMap();
|
|
2136
2259
|
|
|
2137
2260
|
var __defProp = Object.defineProperty;
|
|
2138
2261
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
@@ -2319,258 +2442,298 @@ class PluginTokenHandler {
|
|
|
2319
2442
|
}
|
|
2320
2443
|
}
|
|
2321
2444
|
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2329
|
-
|
|
2330
|
-
|
|
2331
|
-
|
|
2332
|
-
|
|
2333
|
-
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2445
|
+
var __accessCheck$4 = (obj, member, msg) => {
|
|
2446
|
+
if (!member.has(obj))
|
|
2447
|
+
throw TypeError("Cannot " + msg);
|
|
2448
|
+
};
|
|
2449
|
+
var __privateAdd$4 = (obj, member, value) => {
|
|
2450
|
+
if (member.has(obj))
|
|
2451
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
2452
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
2453
|
+
};
|
|
2454
|
+
var __privateMethod$3 = (obj, member, method) => {
|
|
2455
|
+
__accessCheck$4(obj, member, "access private method");
|
|
2456
|
+
return method;
|
|
2457
|
+
};
|
|
2458
|
+
var _getTokenVerificationOptions, getTokenVerificationOptions_fn;
|
|
2459
|
+
const _UserTokenHandler = class _UserTokenHandler {
|
|
2460
|
+
constructor(algorithms, jwksClient) {
|
|
2461
|
+
this.algorithms = algorithms;
|
|
2462
|
+
this.jwksClient = jwksClient;
|
|
2463
|
+
__privateAdd$4(this, _getTokenVerificationOptions);
|
|
2338
2464
|
}
|
|
2339
|
-
static
|
|
2340
|
-
|
|
2341
|
-
const
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2465
|
+
static create(options) {
|
|
2466
|
+
const algorithms = ["ES256"];
|
|
2467
|
+
const jwksClient = new JwksClient(async () => {
|
|
2468
|
+
const url = await options.discovery.getBaseUrl("auth");
|
|
2469
|
+
return new URL(`${url}/.well-known/jwks.json`);
|
|
2470
|
+
});
|
|
2471
|
+
return new _UserTokenHandler(algorithms, jwksClient);
|
|
2472
|
+
}
|
|
2473
|
+
async verifyToken(token) {
|
|
2474
|
+
const verifyOpts = __privateMethod$3(this, _getTokenVerificationOptions, getTokenVerificationOptions_fn).call(this, token);
|
|
2475
|
+
if (!verifyOpts) {
|
|
2476
|
+
return void 0;
|
|
2477
|
+
}
|
|
2478
|
+
await this.jwksClient.refreshKeyStore(token);
|
|
2479
|
+
const { payload } = await jose.jwtVerify(
|
|
2480
|
+
token,
|
|
2481
|
+
this.jwksClient.getKey,
|
|
2482
|
+
verifyOpts
|
|
2483
|
+
).catch((e) => {
|
|
2484
|
+
throw new errors.AuthenticationError("Invalid token", e);
|
|
2485
|
+
});
|
|
2486
|
+
const userEntityRef = payload.sub;
|
|
2487
|
+
if (!userEntityRef) {
|
|
2488
|
+
throw new errors.AuthenticationError("No user sub found in token");
|
|
2489
|
+
}
|
|
2490
|
+
return { userEntityRef };
|
|
2491
|
+
}
|
|
2492
|
+
createLimitedUserToken(backstageToken) {
|
|
2493
|
+
const [headerRaw, payloadRaw] = backstageToken.split(".");
|
|
2494
|
+
const header = JSON.parse(
|
|
2495
|
+
new TextDecoder().decode(jose.base64url.decode(headerRaw))
|
|
2496
|
+
);
|
|
2497
|
+
const payload = JSON.parse(
|
|
2498
|
+
new TextDecoder().decode(jose.base64url.decode(payloadRaw))
|
|
2499
|
+
);
|
|
2500
|
+
const tokenType = header.typ;
|
|
2501
|
+
if (!tokenType || tokenType === pluginAuthNode.tokenTypes.limitedUser.typParam) {
|
|
2502
|
+
return { token: backstageToken, expiresAt: new Date(payload.exp * 1e3) };
|
|
2503
|
+
}
|
|
2504
|
+
if (tokenType !== pluginAuthNode.tokenTypes.user.typParam) {
|
|
2505
|
+
throw new errors.AuthenticationError(
|
|
2506
|
+
"Failed to create limited user token, invalid token type"
|
|
2507
|
+
);
|
|
2508
|
+
}
|
|
2509
|
+
const limitedUserToken = [
|
|
2510
|
+
jose.base64url.encode(
|
|
2511
|
+
JSON.stringify({
|
|
2512
|
+
typ: pluginAuthNode.tokenTypes.limitedUser.typParam,
|
|
2513
|
+
alg: header.alg,
|
|
2514
|
+
kid: header.kid
|
|
2515
|
+
})
|
|
2516
|
+
),
|
|
2517
|
+
jose.base64url.encode(
|
|
2518
|
+
JSON.stringify({
|
|
2519
|
+
sub: payload.sub,
|
|
2520
|
+
ent: payload.ent,
|
|
2521
|
+
iat: payload.iat,
|
|
2522
|
+
exp: payload.exp
|
|
2523
|
+
})
|
|
2524
|
+
),
|
|
2525
|
+
payload.uip
|
|
2526
|
+
].join(".");
|
|
2527
|
+
return { token: limitedUserToken, expiresAt: new Date(payload.exp * 1e3) };
|
|
2528
|
+
}
|
|
2529
|
+
isLimitedUserToken(token) {
|
|
2530
|
+
try {
|
|
2531
|
+
const { typ } = jose.decodeProtectedHeader(token);
|
|
2532
|
+
return typ === pluginAuthNode.tokenTypes.limitedUser.typParam;
|
|
2533
|
+
} catch {
|
|
2534
|
+
return false;
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
};
|
|
2538
|
+
_getTokenVerificationOptions = new WeakSet();
|
|
2539
|
+
getTokenVerificationOptions_fn = function(token) {
|
|
2540
|
+
try {
|
|
2541
|
+
const { typ } = jose.decodeProtectedHeader(token);
|
|
2542
|
+
if (typ === pluginAuthNode.tokenTypes.user.typParam) {
|
|
2543
|
+
return {
|
|
2544
|
+
algorithms: this.algorithms,
|
|
2545
|
+
requiredClaims: ["iat", "exp", "sub"],
|
|
2546
|
+
typ: pluginAuthNode.tokenTypes.user.typParam
|
|
2547
|
+
};
|
|
2548
|
+
}
|
|
2549
|
+
if (typ === pluginAuthNode.tokenTypes.limitedUser.typParam) {
|
|
2550
|
+
return {
|
|
2551
|
+
algorithms: this.algorithms,
|
|
2552
|
+
requiredClaims: ["iat", "exp", "sub"],
|
|
2553
|
+
typ: pluginAuthNode.tokenTypes.limitedUser.typParam
|
|
2554
|
+
};
|
|
2555
|
+
}
|
|
2556
|
+
const { aud } = jose.decodeJwt(token);
|
|
2557
|
+
if (aud === pluginAuthNode.tokenTypes.user.audClaim) {
|
|
2558
|
+
return {
|
|
2559
|
+
algorithms: this.algorithms,
|
|
2560
|
+
audience: pluginAuthNode.tokenTypes.user.audClaim
|
|
2561
|
+
};
|
|
2345
2562
|
}
|
|
2346
|
-
|
|
2563
|
+
} catch {
|
|
2347
2564
|
}
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2565
|
+
return void 0;
|
|
2566
|
+
};
|
|
2567
|
+
let UserTokenHandler = _UserTokenHandler;
|
|
2568
|
+
|
|
2569
|
+
var __accessCheck$3 = (obj, member, msg) => {
|
|
2570
|
+
if (!member.has(obj))
|
|
2571
|
+
throw TypeError("Cannot " + msg);
|
|
2572
|
+
};
|
|
2573
|
+
var __privateGet$3 = (obj, member, getter) => {
|
|
2574
|
+
__accessCheck$3(obj, member, "read from private field");
|
|
2575
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
2576
|
+
};
|
|
2577
|
+
var __privateAdd$3 = (obj, member, value) => {
|
|
2578
|
+
if (member.has(obj))
|
|
2579
|
+
throw TypeError("Cannot add the same private member more than once");
|
|
2580
|
+
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
2581
|
+
};
|
|
2582
|
+
var __privateMethod$2 = (obj, member, method) => {
|
|
2583
|
+
__accessCheck$3(obj, member, "access private method");
|
|
2584
|
+
return method;
|
|
2585
|
+
};
|
|
2586
|
+
var _entries$1, _doAdd, doAdd_fn;
|
|
2587
|
+
class LegacyTokenHandler {
|
|
2588
|
+
constructor() {
|
|
2589
|
+
__privateAdd$3(this, _doAdd);
|
|
2590
|
+
__privateAdd$3(this, _entries$1, []);
|
|
2354
2591
|
}
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
if (
|
|
2366
|
-
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2592
|
+
add(options) {
|
|
2593
|
+
__privateMethod$2(this, _doAdd, doAdd_fn).call(this, options.getString("secret"), options.getString("subject"));
|
|
2594
|
+
}
|
|
2595
|
+
// used only for the old backend.auth.keys array
|
|
2596
|
+
addOld(options) {
|
|
2597
|
+
__privateMethod$2(this, _doAdd, doAdd_fn).call(this, options.getString("secret"), "external:backstage-plugin");
|
|
2598
|
+
}
|
|
2599
|
+
async verifyToken(token) {
|
|
2600
|
+
try {
|
|
2601
|
+
const { alg } = jose.decodeProtectedHeader(token);
|
|
2602
|
+
if (alg !== "HS256") {
|
|
2603
|
+
return void 0;
|
|
2604
|
+
}
|
|
2605
|
+
const { sub, aud } = jose.decodeJwt(token);
|
|
2606
|
+
if (sub !== "backstage-server" || aud) {
|
|
2607
|
+
return void 0;
|
|
2369
2608
|
}
|
|
2609
|
+
} catch (e) {
|
|
2610
|
+
return void 0;
|
|
2370
2611
|
}
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
)
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
);
|
|
2381
|
-
});
|
|
2612
|
+
for (const entry of __privateGet$3(this, _entries$1)) {
|
|
2613
|
+
try {
|
|
2614
|
+
await jose.jwtVerify(token, entry.key);
|
|
2615
|
+
return { subject: entry.subject };
|
|
2616
|
+
} catch (e) {
|
|
2617
|
+
if (e.code !== "ERR_JWS_SIGNATURE_VERIFICATION_FAILED") {
|
|
2618
|
+
throw e;
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2382
2621
|
}
|
|
2383
|
-
return
|
|
2622
|
+
return void 0;
|
|
2384
2623
|
}
|
|
2385
2624
|
}
|
|
2625
|
+
_entries$1 = new WeakMap();
|
|
2626
|
+
_doAdd = new WeakSet();
|
|
2627
|
+
doAdd_fn = function(secret, subject) {
|
|
2628
|
+
if (!secret.match(/^\S+$/)) {
|
|
2629
|
+
throw new Error("Illegal secret, must be a valid base64 string");
|
|
2630
|
+
}
|
|
2631
|
+
let key;
|
|
2632
|
+
try {
|
|
2633
|
+
key = jose.base64url.decode(secret);
|
|
2634
|
+
} catch {
|
|
2635
|
+
throw new Error("Illegal secret, must be a valid base64 string");
|
|
2636
|
+
}
|
|
2637
|
+
if (!subject.match(/^\S+$/)) {
|
|
2638
|
+
throw new Error("Illegal subject, must be a set of non-space characters");
|
|
2639
|
+
}
|
|
2640
|
+
__privateGet$3(this, _entries$1).push({ key, subject });
|
|
2641
|
+
};
|
|
2386
2642
|
|
|
2387
2643
|
var __accessCheck$2 = (obj, member, msg) => {
|
|
2388
2644
|
if (!member.has(obj))
|
|
2389
2645
|
throw TypeError("Cannot " + msg);
|
|
2390
2646
|
};
|
|
2647
|
+
var __privateGet$2 = (obj, member, getter) => {
|
|
2648
|
+
__accessCheck$2(obj, member, "read from private field");
|
|
2649
|
+
return getter ? getter.call(obj) : member.get(obj);
|
|
2650
|
+
};
|
|
2391
2651
|
var __privateAdd$2 = (obj, member, value) => {
|
|
2392
2652
|
if (member.has(obj))
|
|
2393
2653
|
throw TypeError("Cannot add the same private member more than once");
|
|
2394
2654
|
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
2395
2655
|
};
|
|
2396
|
-
var
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
principal: {
|
|
2407
|
-
type: "service",
|
|
2408
|
-
subject: sub
|
|
2656
|
+
var _entries;
|
|
2657
|
+
const MIN_TOKEN_LENGTH = 8;
|
|
2658
|
+
class StaticTokenHandler {
|
|
2659
|
+
constructor() {
|
|
2660
|
+
__privateAdd$2(this, _entries, []);
|
|
2661
|
+
}
|
|
2662
|
+
add(options) {
|
|
2663
|
+
const token = options.getString("token");
|
|
2664
|
+
if (!token.match(/^\S+$/)) {
|
|
2665
|
+
throw new Error("Illegal token, must be a set of non-space characters");
|
|
2409
2666
|
}
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
$$type: "@backstage/BackstageCredentials",
|
|
2415
|
-
version: "v1",
|
|
2416
|
-
token,
|
|
2417
|
-
expiresAt,
|
|
2418
|
-
principal: {
|
|
2419
|
-
type: "user",
|
|
2420
|
-
userEntityRef: sub
|
|
2667
|
+
if (token.length < MIN_TOKEN_LENGTH) {
|
|
2668
|
+
throw new Error(
|
|
2669
|
+
`Illegal token, must be at least ${MIN_TOKEN_LENGTH} characters length`
|
|
2670
|
+
);
|
|
2421
2671
|
}
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
return {
|
|
2426
|
-
$$type: "@backstage/BackstageCredentials",
|
|
2427
|
-
version: "v1",
|
|
2428
|
-
principal: {
|
|
2429
|
-
type: "none"
|
|
2672
|
+
const subject = options.getString("subject");
|
|
2673
|
+
if (!subject.match(/^\S+$/)) {
|
|
2674
|
+
throw new Error("Illegal subject, must be a set of non-space characters");
|
|
2430
2675
|
}
|
|
2431
|
-
|
|
2432
|
-
}
|
|
2433
|
-
function toInternalBackstageCredentials(credentials) {
|
|
2434
|
-
if (credentials.$$type !== "@backstage/BackstageCredentials") {
|
|
2435
|
-
throw new Error("Invalid credential type");
|
|
2676
|
+
__privateGet$2(this, _entries).push({ token, subject });
|
|
2436
2677
|
}
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2678
|
+
async verifyToken(token) {
|
|
2679
|
+
const entry = __privateGet$2(this, _entries).find((e) => e.token === token);
|
|
2680
|
+
if (!entry) {
|
|
2681
|
+
return void 0;
|
|
2682
|
+
}
|
|
2683
|
+
return { subject: entry.subject };
|
|
2442
2684
|
}
|
|
2443
|
-
return internalCredentials;
|
|
2444
2685
|
}
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
this.
|
|
2452
|
-
this.pluginTokenHandler = pluginTokenHandler;
|
|
2453
|
-
__privateAdd$2(this, _getJwtExpiration);
|
|
2686
|
+
_entries = new WeakMap();
|
|
2687
|
+
|
|
2688
|
+
const NEW_CONFIG_KEY = "backend.auth.externalAccess";
|
|
2689
|
+
const OLD_CONFIG_KEY = "backend.auth.keys";
|
|
2690
|
+
class ExternalTokenHandler {
|
|
2691
|
+
constructor(handlers) {
|
|
2692
|
+
this.handlers = handlers;
|
|
2454
2693
|
}
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
const
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2694
|
+
static create(options) {
|
|
2695
|
+
var _a, _b;
|
|
2696
|
+
const { config, logger } = options;
|
|
2697
|
+
const staticHandler = new StaticTokenHandler();
|
|
2698
|
+
const legacyHandler = new LegacyTokenHandler();
|
|
2699
|
+
const handlers = {
|
|
2700
|
+
static: staticHandler,
|
|
2701
|
+
legacy: legacyHandler
|
|
2702
|
+
};
|
|
2703
|
+
const handlerConfigs = (_a = config.getOptionalConfigArray(NEW_CONFIG_KEY)) != null ? _a : [];
|
|
2704
|
+
for (const handlerConfig of handlerConfigs) {
|
|
2705
|
+
const type = handlerConfig.getString("type");
|
|
2706
|
+
const handler = handlers[type];
|
|
2707
|
+
if (!handler) {
|
|
2708
|
+
const valid = Object.keys(handlers).map((k) => `'${k}'`).join(", ");
|
|
2709
|
+
throw new Error(
|
|
2710
|
+
`Unknown type '${type}' in ${NEW_CONFIG_KEY}, expected one of ${valid}`
|
|
2472
2711
|
);
|
|
2473
2712
|
}
|
|
2474
|
-
|
|
2713
|
+
handler.add(handlerConfig.getConfig("options"));
|
|
2475
2714
|
}
|
|
2476
|
-
const
|
|
2477
|
-
if (
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
token,
|
|
2481
|
-
__privateMethod$2(this, _getJwtExpiration, getJwtExpiration_fn).call(this, token)
|
|
2715
|
+
const legacyConfigs = (_b = config.getOptionalConfigArray(OLD_CONFIG_KEY)) != null ? _b : [];
|
|
2716
|
+
if (legacyConfigs.length) {
|
|
2717
|
+
logger.warn(
|
|
2718
|
+
`DEPRECATION WARNING: The ${OLD_CONFIG_KEY} config has been replaced by ${NEW_CONFIG_KEY}, see https://backstage.io/docs/auth/service-to-service-auth`
|
|
2482
2719
|
);
|
|
2483
2720
|
}
|
|
2484
|
-
const
|
|
2485
|
-
|
|
2486
|
-
await this.tokenManager.authenticate(token);
|
|
2487
|
-
return createCredentialsWithServicePrincipal("external:backstage-plugin");
|
|
2488
|
-
}
|
|
2489
|
-
throw new errors.AuthenticationError("Unknown token");
|
|
2490
|
-
}
|
|
2491
|
-
isPrincipal(credentials, type) {
|
|
2492
|
-
const principal = credentials.principal;
|
|
2493
|
-
if (type === "unknown") {
|
|
2494
|
-
return true;
|
|
2495
|
-
}
|
|
2496
|
-
if (principal.type !== type) {
|
|
2497
|
-
return false;
|
|
2721
|
+
for (const handlerConfig of legacyConfigs) {
|
|
2722
|
+
legacyHandler.addOld(handlerConfig);
|
|
2498
2723
|
}
|
|
2499
|
-
return
|
|
2500
|
-
}
|
|
2501
|
-
async getNoneCredentials() {
|
|
2502
|
-
return createCredentialsWithNonePrincipal();
|
|
2503
|
-
}
|
|
2504
|
-
async getOwnServiceCredentials() {
|
|
2505
|
-
return createCredentialsWithServicePrincipal(`plugin:${this.pluginId}`);
|
|
2724
|
+
return new ExternalTokenHandler(Object.values(handlers));
|
|
2506
2725
|
}
|
|
2507
|
-
async
|
|
2508
|
-
const
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
return { token: "" };
|
|
2513
|
-
}
|
|
2514
|
-
const targetSupportsNewAuth = await this.pluginTokenHandler.isTargetPluginSupported(targetPluginId);
|
|
2515
|
-
switch (type) {
|
|
2516
|
-
case "service":
|
|
2517
|
-
if (targetSupportsNewAuth) {
|
|
2518
|
-
return this.pluginTokenHandler.issueToken({
|
|
2519
|
-
pluginId: this.pluginId,
|
|
2520
|
-
targetPluginId
|
|
2521
|
-
});
|
|
2522
|
-
}
|
|
2523
|
-
return this.tokenManager.getToken();
|
|
2524
|
-
case "user": {
|
|
2525
|
-
const { token } = internalForward;
|
|
2526
|
-
if (!token) {
|
|
2527
|
-
throw new Error("User credentials is unexpectedly missing token");
|
|
2528
|
-
}
|
|
2529
|
-
if (targetSupportsNewAuth) {
|
|
2530
|
-
const onBehalfOf = await this.userTokenHandler.createLimitedUserToken(
|
|
2531
|
-
token
|
|
2532
|
-
);
|
|
2533
|
-
return this.pluginTokenHandler.issueToken({
|
|
2534
|
-
pluginId: this.pluginId,
|
|
2535
|
-
targetPluginId,
|
|
2536
|
-
onBehalfOf
|
|
2537
|
-
});
|
|
2538
|
-
}
|
|
2539
|
-
if (this.userTokenHandler.isLimitedUserToken(token)) {
|
|
2540
|
-
throw new errors.AuthenticationError(
|
|
2541
|
-
`Unable to call '${targetPluginId}' plugin on behalf of user, because the target plugin does not support on-behalf-of tokens`
|
|
2542
|
-
);
|
|
2543
|
-
}
|
|
2544
|
-
return { token };
|
|
2726
|
+
async verifyToken(token) {
|
|
2727
|
+
for (const handler of this.handlers) {
|
|
2728
|
+
const result = await handler.verifyToken(token);
|
|
2729
|
+
if (result) {
|
|
2730
|
+
return result;
|
|
2545
2731
|
}
|
|
2546
|
-
default:
|
|
2547
|
-
throw new errors.AuthenticationError(
|
|
2548
|
-
`Refused to issue service token for credential type '${type}'`
|
|
2549
|
-
);
|
|
2550
|
-
}
|
|
2551
|
-
}
|
|
2552
|
-
async getLimitedUserToken(credentials) {
|
|
2553
|
-
const { token: backstageToken } = toInternalBackstageCredentials(credentials);
|
|
2554
|
-
if (!backstageToken) {
|
|
2555
|
-
throw new errors.AuthenticationError(
|
|
2556
|
-
"User credentials is unexpectedly missing token"
|
|
2557
|
-
);
|
|
2558
2732
|
}
|
|
2559
|
-
return
|
|
2560
|
-
}
|
|
2561
|
-
async listPublicServiceKeys() {
|
|
2562
|
-
const { keys } = await this.publicKeyStore.listKeys();
|
|
2563
|
-
return { keys: keys.map(({ key }) => key) };
|
|
2733
|
+
return void 0;
|
|
2564
2734
|
}
|
|
2565
2735
|
}
|
|
2566
|
-
|
|
2567
|
-
getJwtExpiration_fn = function(token) {
|
|
2568
|
-
const { exp } = jose.decodeJwt(token);
|
|
2569
|
-
if (!exp) {
|
|
2570
|
-
throw new errors.AuthenticationError("User token is missing expiration");
|
|
2571
|
-
}
|
|
2572
|
-
return new Date(exp * 1e3);
|
|
2573
|
-
};
|
|
2736
|
+
|
|
2574
2737
|
const authServiceFactory = backendPluginApi.createServiceFactory({
|
|
2575
2738
|
service: backendPluginApi.coreServices.auth,
|
|
2576
2739
|
deps: {
|
|
@@ -2591,20 +2754,32 @@ const authServiceFactory = backendPluginApi.createServiceFactory({
|
|
|
2591
2754
|
"backend.auth.dangerouslyDisableDefaultAuthPolicy"
|
|
2592
2755
|
)
|
|
2593
2756
|
);
|
|
2594
|
-
const publicKeyStore = await DatabaseKeyStore.create({
|
|
2757
|
+
const publicKeyStore = await DatabaseKeyStore.create({
|
|
2758
|
+
database,
|
|
2759
|
+
logger
|
|
2760
|
+
});
|
|
2761
|
+
const userTokens = UserTokenHandler.create({
|
|
2762
|
+
discovery
|
|
2763
|
+
});
|
|
2764
|
+
const pluginTokens = PluginTokenHandler.create({
|
|
2765
|
+
ownPluginId: plugin.getId(),
|
|
2766
|
+
keyDurationSeconds: 60 * 60,
|
|
2767
|
+
logger,
|
|
2768
|
+
publicKeyStore,
|
|
2769
|
+
discovery
|
|
2770
|
+
});
|
|
2771
|
+
const externalTokens = ExternalTokenHandler.create({
|
|
2772
|
+
config,
|
|
2773
|
+
logger
|
|
2774
|
+
});
|
|
2595
2775
|
return new DefaultAuthService(
|
|
2776
|
+
userTokens,
|
|
2777
|
+
pluginTokens,
|
|
2778
|
+
externalTokens,
|
|
2596
2779
|
tokenManager,
|
|
2597
|
-
new UserTokenHandler({ discovery }),
|
|
2598
2780
|
plugin.getId(),
|
|
2599
2781
|
disableDefaultAuthPolicy,
|
|
2600
|
-
publicKeyStore
|
|
2601
|
-
PluginTokenHandler.create({
|
|
2602
|
-
ownPluginId: plugin.getId(),
|
|
2603
|
-
keyDurationSeconds: 60 * 60,
|
|
2604
|
-
logger,
|
|
2605
|
-
publicKeyStore,
|
|
2606
|
-
discovery
|
|
2607
|
-
})
|
|
2782
|
+
publicKeyStore
|
|
2608
2783
|
);
|
|
2609
2784
|
}
|
|
2610
2785
|
});
|
|
@@ -2928,13 +3103,11 @@ getLimitedCredentials_fn = async function(req) {
|
|
|
2928
3103
|
return (_a = req[limitedCredentialsSymbol]) != null ? _a : req[limitedCredentialsSymbol] = __privateMethod$1(this, _extractLimitedCredentialsFromRequest, extractLimitedCredentialsFromRequest_fn).call(this, req);
|
|
2929
3104
|
};
|
|
2930
3105
|
_getCookieOptions = new WeakSet();
|
|
2931
|
-
getCookieOptions_fn = async function(
|
|
2932
|
-
const originHeader = req.headers.origin;
|
|
2933
|
-
const origin = !originHeader || originHeader === "null" ? void 0 : originHeader;
|
|
3106
|
+
getCookieOptions_fn = async function(_req) {
|
|
2934
3107
|
const externalBaseUrlStr = await __privateGet$1(this, _discovery).getExternalBaseUrl(
|
|
2935
3108
|
__privateGet$1(this, _pluginId)
|
|
2936
3109
|
);
|
|
2937
|
-
const externalBaseUrl = new URL(
|
|
3110
|
+
const externalBaseUrl = new URL(externalBaseUrlStr);
|
|
2938
3111
|
const secure = externalBaseUrl.protocol === "https:" || externalBaseUrl.hostname === "localhost";
|
|
2939
3112
|
return {
|
|
2940
3113
|
domain: externalBaseUrl.hostname,
|
|
@@ -3371,7 +3544,7 @@ const schedulerServiceFactory = backendPluginApi.createServiceFactory({
|
|
|
3371
3544
|
return backendTasks.TaskScheduler.forPlugin({
|
|
3372
3545
|
pluginId: plugin.getId(),
|
|
3373
3546
|
databaseManager,
|
|
3374
|
-
logger
|
|
3547
|
+
logger
|
|
3375
3548
|
});
|
|
3376
3549
|
}
|
|
3377
3550
|
});
|
|
@@ -3401,7 +3574,7 @@ const urlReaderServiceFactory = backendPluginApi.createServiceFactory({
|
|
|
3401
3574
|
async factory({ config, logger }) {
|
|
3402
3575
|
return backendCommon.UrlReaders.default({
|
|
3403
3576
|
config,
|
|
3404
|
-
logger
|
|
3577
|
+
logger
|
|
3405
3578
|
});
|
|
3406
3579
|
}
|
|
3407
3580
|
});
|