@backstage/backend-app-api 0.7.0-next.1 → 0.7.1-next.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/dist/index.cjs.js CHANGED
@@ -21,15 +21,15 @@ 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
+ var types = require('@backstage/types');
29
30
  var backendAppApi = require('@backstage/backend-app-api');
30
31
  var cookie = require('cookie');
31
32
  var Router = require('express-promise-router');
32
- var types = require('@backstage/types');
33
33
  var pathToRegexp = require('path-to-regexp');
34
34
  var pluginPermissionNode = require('@backstage/plugin-permission-node');
35
35
  var express = require('express');
@@ -612,31 +612,31 @@ function applyInternalErrorFilter(error, logger) {
612
612
  return error;
613
613
  }
614
614
 
615
- var __accessCheck$c = (obj, member, msg) => {
615
+ var __accessCheck$e = (obj, member, msg) => {
616
616
  if (!member.has(obj))
617
617
  throw TypeError("Cannot " + msg);
618
618
  };
619
- var __privateGet$b = (obj, member, getter) => {
620
- __accessCheck$c(obj, member, "read from private field");
621
- return getter ? getter.call(obj) : member.get(obj);
619
+ var __privateGet$c = (obj, member, getter) => {
620
+ __accessCheck$e(obj, member, "read from private field");
621
+ return member.get(obj);
622
622
  };
623
- var __privateAdd$c = (obj, member, value) => {
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$b = (obj, member, value, setter) => {
629
- __accessCheck$c(obj, member, "write to private field");
630
- setter ? setter.call(obj, value) : member.set(obj, value);
628
+ var __privateSet$a = (obj, member, value, setter) => {
629
+ __accessCheck$e(obj, member, "write to private field");
630
+ 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$c(this, _config, void 0);
637
- __privateAdd$c(this, _logger, void 0);
638
- __privateSet$b(this, _config, options.config);
639
- __privateSet$b(this, _logger, options.logger);
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$b(this, _logger).child({
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$b(this, _config).getOptionalConfig("backend")));
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$b(this, _config).getOptionalConfig("backend")));
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$b(this, _logger).child({
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$b = (obj, member, msg) => {
808
+ var __accessCheck$d = (obj, member, msg) => {
809
809
  if (!member.has(obj))
810
810
  throw TypeError("Cannot " + msg);
811
811
  };
812
- var __privateGet$a = (obj, member, getter) => {
813
- __accessCheck$b(obj, member, "read from private field");
814
- return getter ? getter.call(obj) : member.get(obj);
812
+ var __privateGet$b = (obj, member, getter) => {
813
+ __accessCheck$d(obj, member, "read from private field");
814
+ return member.get(obj);
815
815
  };
816
- var __privateAdd$b = (obj, member, value) => {
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$a = (obj, member, value, setter) => {
822
- __accessCheck$b(obj, member, "write to private field");
823
- setter ? setter.call(obj, value) : member.set(obj, value);
821
+ var __privateSet$9 = (obj, member, value, setter) => {
822
+ __accessCheck$d(obj, member, "write to private field");
823
+ 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$b(this, _winston, void 0);
830
- __privateAdd$b(this, _addRedactions, void 0);
831
- __privateSet$a(this, _winston, winston);
832
- __privateSet$a(this, _addRedactions, addRedactions);
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.
@@ -857,16 +857,21 @@ const _WinstonLogger = class _WinstonLogger {
857
857
  static redacter() {
858
858
  const redactionSet = /* @__PURE__ */ new Set();
859
859
  let redactionPattern = void 0;
860
- return {
861
- format: winston.format((info) => {
862
- if (redactionPattern && typeof info.message === "string") {
863
- info.message = info.message.replace(redactionPattern, "[REDACTED]");
864
- }
865
- if (redactionPattern && typeof info.stack === "string") {
866
- info.stack = info.stack.replace(redactionPattern, "[REDACTED]");
860
+ const replace = (obj) => {
861
+ var _a;
862
+ for (const key in obj) {
863
+ if (obj.hasOwnProperty(key)) {
864
+ if (typeof obj[key] === "object") {
865
+ obj[key] = replace(obj[key]);
866
+ } else if (typeof obj[key] === "string") {
867
+ obj[key] = (_a = obj[key]) == null ? void 0 : _a.replace(redactionPattern, "[REDACTED]");
868
+ }
867
869
  }
868
- return info;
869
- })(),
870
+ }
871
+ return obj;
872
+ };
873
+ return {
874
+ format: winston.format(replace)(),
870
875
  add(newRedactions) {
871
876
  let added = 0;
872
877
  for (const redactionToTrim of newRedactions) {
@@ -914,70 +919,70 @@ const _WinstonLogger = class _WinstonLogger {
914
919
  );
915
920
  }
916
921
  error(message, meta) {
917
- __privateGet$a(this, _winston).error(message, meta);
922
+ __privateGet$b(this, _winston).error(message, meta);
918
923
  }
919
924
  warn(message, meta) {
920
- __privateGet$a(this, _winston).warn(message, meta);
925
+ __privateGet$b(this, _winston).warn(message, meta);
921
926
  }
922
927
  info(message, meta) {
923
- __privateGet$a(this, _winston).info(message, meta);
928
+ __privateGet$b(this, _winston).info(message, meta);
924
929
  }
925
930
  debug(message, meta) {
926
- __privateGet$a(this, _winston).debug(message, meta);
931
+ __privateGet$b(this, _winston).debug(message, meta);
927
932
  }
928
933
  child(meta) {
929
- return new _WinstonLogger(__privateGet$a(this, _winston).child(meta));
934
+ return new _WinstonLogger(__privateGet$b(this, _winston).child(meta));
930
935
  }
931
936
  addRedactions(redactions) {
932
937
  var _a;
933
- (_a = __privateGet$a(this, _addRedactions)) == null ? void 0 : _a.call(this, redactions);
938
+ (_a = __privateGet$b(this, _addRedactions)) == null ? void 0 : _a.call(this, redactions);
934
939
  }
935
940
  };
936
941
  _winston = new WeakMap();
937
942
  _addRedactions = new WeakMap();
938
943
  let WinstonLogger = _WinstonLogger;
939
944
 
940
- var __accessCheck$a = (obj, member, msg) => {
945
+ var __accessCheck$c = (obj, member, msg) => {
941
946
  if (!member.has(obj))
942
947
  throw TypeError("Cannot " + msg);
943
948
  };
944
- var __privateGet$9 = (obj, member, getter) => {
945
- __accessCheck$a(obj, member, "read from private field");
946
- return getter ? getter.call(obj) : member.get(obj);
949
+ var __privateGet$a = (obj, member, getter) => {
950
+ __accessCheck$c(obj, member, "read from private field");
951
+ return member.get(obj);
947
952
  };
948
- var __privateAdd$a = (obj, member, value) => {
953
+ var __privateAdd$c = (obj, member, value) => {
949
954
  if (member.has(obj))
950
955
  throw TypeError("Cannot add the same private member more than once");
951
956
  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
952
957
  };
953
- var __privateSet$9 = (obj, member, value, setter) => {
954
- __accessCheck$a(obj, member, "write to private field");
955
- setter ? setter.call(obj, value) : member.set(obj, value);
958
+ var __privateSet$8 = (obj, member, value, setter) => {
959
+ __accessCheck$c(obj, member, "write to private field");
960
+ member.set(obj, value);
956
961
  return value;
957
962
  };
958
963
  var _hasStarted$1, _startupTasks$1, _hasShutdown, _shutdownTasks;
959
964
  class BackendLifecycleImpl {
960
965
  constructor(logger) {
961
966
  this.logger = logger;
962
- __privateAdd$a(this, _hasStarted$1, false);
963
- __privateAdd$a(this, _startupTasks$1, []);
964
- __privateAdd$a(this, _hasShutdown, false);
965
- __privateAdd$a(this, _shutdownTasks, []);
967
+ __privateAdd$c(this, _hasStarted$1, false);
968
+ __privateAdd$c(this, _startupTasks$1, []);
969
+ __privateAdd$c(this, _hasShutdown, false);
970
+ __privateAdd$c(this, _shutdownTasks, []);
966
971
  }
967
972
  addStartupHook(hook, options) {
968
- if (__privateGet$9(this, _hasStarted$1)) {
973
+ if (__privateGet$a(this, _hasStarted$1)) {
969
974
  throw new Error("Attempted to add startup hook after startup");
970
975
  }
971
- __privateGet$9(this, _startupTasks$1).push({ hook, options });
976
+ __privateGet$a(this, _startupTasks$1).push({ hook, options });
972
977
  }
973
978
  async startup() {
974
- if (__privateGet$9(this, _hasStarted$1)) {
979
+ if (__privateGet$a(this, _hasStarted$1)) {
975
980
  return;
976
981
  }
977
- __privateSet$9(this, _hasStarted$1, true);
978
- this.logger.debug(`Running ${__privateGet$9(this, _startupTasks$1).length} startup tasks...`);
982
+ __privateSet$8(this, _hasStarted$1, true);
983
+ this.logger.debug(`Running ${__privateGet$a(this, _startupTasks$1).length} startup tasks...`);
979
984
  await Promise.all(
980
- __privateGet$9(this, _startupTasks$1).map(async ({ hook, options }) => {
985
+ __privateGet$a(this, _startupTasks$1).map(async ({ hook, options }) => {
981
986
  var _a;
982
987
  const logger = (_a = options == null ? void 0 : options.logger) != null ? _a : this.logger;
983
988
  try {
@@ -990,21 +995,21 @@ class BackendLifecycleImpl {
990
995
  );
991
996
  }
992
997
  addShutdownHook(hook, options) {
993
- if (__privateGet$9(this, _hasShutdown)) {
998
+ if (__privateGet$a(this, _hasShutdown)) {
994
999
  throw new Error("Attempted to add shutdown hook after shutdown");
995
1000
  }
996
- __privateGet$9(this, _shutdownTasks).push({ hook, options });
1001
+ __privateGet$a(this, _shutdownTasks).push({ hook, options });
997
1002
  }
998
1003
  async shutdown() {
999
- if (__privateGet$9(this, _hasShutdown)) {
1004
+ if (__privateGet$a(this, _hasShutdown)) {
1000
1005
  return;
1001
1006
  }
1002
- __privateSet$9(this, _hasShutdown, true);
1007
+ __privateSet$8(this, _hasShutdown, true);
1003
1008
  this.logger.debug(
1004
- `Running ${__privateGet$9(this, _shutdownTasks).length} shutdown tasks...`
1009
+ `Running ${__privateGet$a(this, _shutdownTasks).length} shutdown tasks...`
1005
1010
  );
1006
1011
  await Promise.all(
1007
- __privateGet$9(this, _shutdownTasks).map(async ({ hook, options }) => {
1012
+ __privateGet$a(this, _shutdownTasks).map(async ({ hook, options }) => {
1008
1013
  var _a;
1009
1014
  const logger = (_a = options == null ? void 0 : options.logger) != null ? _a : this.logger;
1010
1015
  try {
@@ -1031,22 +1036,22 @@ const rootLifecycleServiceFactory = backendPluginApi.createServiceFactory({
1031
1036
  }
1032
1037
  });
1033
1038
 
1034
- var __accessCheck$9 = (obj, member, msg) => {
1039
+ var __accessCheck$b = (obj, member, msg) => {
1035
1040
  if (!member.has(obj))
1036
1041
  throw TypeError("Cannot " + msg);
1037
1042
  };
1038
- var __privateGet$8 = (obj, member, getter) => {
1039
- __accessCheck$9(obj, member, "read from private field");
1040
- return getter ? getter.call(obj) : member.get(obj);
1043
+ var __privateGet$9 = (obj, member, getter) => {
1044
+ __accessCheck$b(obj, member, "read from private field");
1045
+ return member.get(obj);
1041
1046
  };
1042
- var __privateAdd$9 = (obj, member, value) => {
1047
+ var __privateAdd$b = (obj, member, value) => {
1043
1048
  if (member.has(obj))
1044
1049
  throw TypeError("Cannot add the same private member more than once");
1045
1050
  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1046
1051
  };
1047
- var __privateSet$8 = (obj, member, value, setter) => {
1048
- __accessCheck$9(obj, member, "write to private field");
1049
- setter ? setter.call(obj, value) : member.set(obj, value);
1052
+ var __privateSet$7 = (obj, member, value, setter) => {
1053
+ __accessCheck$b(obj, member, "write to private field");
1054
+ member.set(obj, value);
1050
1055
  return value;
1051
1056
  };
1052
1057
  var _hasStarted, _startupTasks;
@@ -1055,25 +1060,25 @@ class BackendPluginLifecycleImpl {
1055
1060
  this.logger = logger;
1056
1061
  this.rootLifecycle = rootLifecycle;
1057
1062
  this.pluginMetadata = pluginMetadata;
1058
- __privateAdd$9(this, _hasStarted, false);
1059
- __privateAdd$9(this, _startupTasks, []);
1063
+ __privateAdd$b(this, _hasStarted, false);
1064
+ __privateAdd$b(this, _startupTasks, []);
1060
1065
  }
1061
1066
  addStartupHook(hook, options) {
1062
- if (__privateGet$8(this, _hasStarted)) {
1067
+ if (__privateGet$9(this, _hasStarted)) {
1063
1068
  throw new Error("Attempted to add startup hook after startup");
1064
1069
  }
1065
- __privateGet$8(this, _startupTasks).push({ hook, options });
1070
+ __privateGet$9(this, _startupTasks).push({ hook, options });
1066
1071
  }
1067
1072
  async startup() {
1068
- if (__privateGet$8(this, _hasStarted)) {
1073
+ if (__privateGet$9(this, _hasStarted)) {
1069
1074
  return;
1070
1075
  }
1071
- __privateSet$8(this, _hasStarted, true);
1076
+ __privateSet$7(this, _hasStarted, true);
1072
1077
  this.logger.debug(
1073
- `Running ${__privateGet$8(this, _startupTasks).length} plugin startup tasks...`
1078
+ `Running ${__privateGet$9(this, _startupTasks).length} plugin startup tasks...`
1074
1079
  );
1075
1080
  await Promise.all(
1076
- __privateGet$8(this, _startupTasks).map(async ({ hook, options }) => {
1081
+ __privateGet$9(this, _startupTasks).map(async ({ hook, options }) => {
1077
1082
  var _a;
1078
1083
  const logger = (_a = options == null ? void 0 : options.logger) != null ? _a : this.logger;
1079
1084
  try {
@@ -1111,26 +1116,26 @@ const lifecycleServiceFactory = backendPluginApi.createServiceFactory({
1111
1116
  }
1112
1117
  });
1113
1118
 
1114
- var __accessCheck$8 = (obj, member, msg) => {
1119
+ var __accessCheck$a = (obj, member, msg) => {
1115
1120
  if (!member.has(obj))
1116
1121
  throw TypeError("Cannot " + msg);
1117
1122
  };
1118
- var __privateGet$7 = (obj, member, getter) => {
1119
- __accessCheck$8(obj, member, "read from private field");
1120
- return getter ? getter.call(obj) : member.get(obj);
1123
+ var __privateGet$8 = (obj, member, getter) => {
1124
+ __accessCheck$a(obj, member, "read from private field");
1125
+ return member.get(obj);
1121
1126
  };
1122
- var __privateAdd$8 = (obj, member, value) => {
1127
+ var __privateAdd$a = (obj, member, value) => {
1123
1128
  if (member.has(obj))
1124
1129
  throw TypeError("Cannot add the same private member more than once");
1125
1130
  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1126
1131
  };
1127
- var __privateSet$7 = (obj, member, value, setter) => {
1128
- __accessCheck$8(obj, member, "write to private field");
1129
- setter ? setter.call(obj, value) : member.set(obj, value);
1132
+ var __privateSet$6 = (obj, member, value, setter) => {
1133
+ __accessCheck$a(obj, member, "write to private field");
1134
+ member.set(obj, value);
1130
1135
  return value;
1131
1136
  };
1132
- var __privateMethod$6 = (obj, member, method) => {
1133
- __accessCheck$8(obj, member, "access private method");
1137
+ var __privateMethod$7 = (obj, member, method) => {
1138
+ __accessCheck$a(obj, member, "access private method");
1134
1139
  return method;
1135
1140
  };
1136
1141
  var _nodeIds, _cycleKeys, _getCycleKey, getCycleKey_fn, _nodes, _allProvided;
@@ -1150,21 +1155,21 @@ class Node {
1150
1155
  }
1151
1156
  const _CycleKeySet = class _CycleKeySet {
1152
1157
  constructor(nodes) {
1153
- __privateAdd$8(this, _getCycleKey);
1154
- __privateAdd$8(this, _nodeIds, void 0);
1155
- __privateAdd$8(this, _cycleKeys, void 0);
1156
- __privateSet$7(this, _nodeIds, new Map(nodes.map((n, i) => [n.value, i])));
1157
- __privateSet$7(this, _cycleKeys, /* @__PURE__ */ new Set());
1158
+ __privateAdd$a(this, _getCycleKey);
1159
+ __privateAdd$a(this, _nodeIds, void 0);
1160
+ __privateAdd$a(this, _cycleKeys, void 0);
1161
+ __privateSet$6(this, _nodeIds, new Map(nodes.map((n, i) => [n.value, i])));
1162
+ __privateSet$6(this, _cycleKeys, /* @__PURE__ */ new Set());
1158
1163
  }
1159
1164
  static from(nodes) {
1160
1165
  return new _CycleKeySet(nodes);
1161
1166
  }
1162
1167
  tryAdd(path) {
1163
- const cycleKey = __privateMethod$6(this, _getCycleKey, getCycleKey_fn).call(this, path);
1164
- if (__privateGet$7(this, _cycleKeys).has(cycleKey)) {
1168
+ const cycleKey = __privateMethod$7(this, _getCycleKey, getCycleKey_fn).call(this, path);
1169
+ if (__privateGet$8(this, _cycleKeys).has(cycleKey)) {
1165
1170
  return false;
1166
1171
  }
1167
- __privateGet$7(this, _cycleKeys).add(cycleKey);
1172
+ __privateGet$8(this, _cycleKeys).add(cycleKey);
1168
1173
  return true;
1169
1174
  }
1170
1175
  };
@@ -1172,18 +1177,18 @@ _nodeIds = new WeakMap();
1172
1177
  _cycleKeys = new WeakMap();
1173
1178
  _getCycleKey = new WeakSet();
1174
1179
  getCycleKey_fn = function(path) {
1175
- return path.map((n) => __privateGet$7(this, _nodeIds).get(n)).sort().join(",");
1180
+ return path.map((n) => __privateGet$8(this, _nodeIds).get(n)).sort().join(",");
1176
1181
  };
1177
1182
  let CycleKeySet = _CycleKeySet;
1178
1183
  const _DependencyGraph = class _DependencyGraph {
1179
1184
  constructor(nodes) {
1180
- __privateAdd$8(this, _nodes, void 0);
1181
- __privateAdd$8(this, _allProvided, void 0);
1182
- __privateSet$7(this, _nodes, nodes);
1183
- __privateSet$7(this, _allProvided, /* @__PURE__ */ new Set());
1184
- for (const node of __privateGet$7(this, _nodes).values()) {
1185
+ __privateAdd$a(this, _nodes, void 0);
1186
+ __privateAdd$a(this, _allProvided, void 0);
1187
+ __privateSet$6(this, _nodes, nodes);
1188
+ __privateSet$6(this, _allProvided, /* @__PURE__ */ new Set());
1189
+ for (const node of __privateGet$8(this, _nodes).values()) {
1185
1190
  for (const produced of node.provides) {
1186
- __privateGet$7(this, _allProvided).add(produced);
1191
+ __privateGet$8(this, _allProvided).add(produced);
1187
1192
  }
1188
1193
  }
1189
1194
  }
@@ -1207,9 +1212,9 @@ const _DependencyGraph = class _DependencyGraph {
1207
1212
  */
1208
1213
  findUnsatisfiedDeps() {
1209
1214
  const unsatisfiedDependencies = [];
1210
- for (const node of __privateGet$7(this, _nodes).values()) {
1215
+ for (const node of __privateGet$8(this, _nodes).values()) {
1211
1216
  const unsatisfied = Array.from(node.consumes).filter(
1212
- (id) => !__privateGet$7(this, _allProvided).has(id)
1217
+ (id) => !__privateGet$8(this, _allProvided).has(id)
1213
1218
  );
1214
1219
  if (unsatisfied.length > 0) {
1215
1220
  unsatisfiedDependencies.push({ value: node.value, unsatisfied });
@@ -1229,8 +1234,8 @@ const _DependencyGraph = class _DependencyGraph {
1229
1234
  * form a cycle, with the same node as the first and last element of the array.
1230
1235
  */
1231
1236
  *detectCircularDependencies() {
1232
- const cycleKeys = CycleKeySet.from(__privateGet$7(this, _nodes));
1233
- for (const startNode of __privateGet$7(this, _nodes)) {
1237
+ const cycleKeys = CycleKeySet.from(__privateGet$8(this, _nodes));
1238
+ for (const startNode of __privateGet$8(this, _nodes)) {
1234
1239
  const visited = /* @__PURE__ */ new Set();
1235
1240
  const stack = new Array([
1236
1241
  startNode,
@@ -1243,7 +1248,7 @@ const _DependencyGraph = class _DependencyGraph {
1243
1248
  }
1244
1249
  visited.add(node);
1245
1250
  for (const consumed of node.consumes) {
1246
- const providerNodes = __privateGet$7(this, _nodes).filter(
1251
+ const providerNodes = __privateGet$8(this, _nodes).filter(
1247
1252
  (other) => other.provides.has(consumed)
1248
1253
  );
1249
1254
  for (const provider of providerNodes) {
@@ -1272,9 +1277,9 @@ const _DependencyGraph = class _DependencyGraph {
1272
1277
  * Dependencies of nodes that are not produced by any other nodes will be ignored.
1273
1278
  */
1274
1279
  async parallelTopologicalTraversal(fn) {
1275
- const allProvided = __privateGet$7(this, _allProvided);
1280
+ const allProvided = __privateGet$8(this, _allProvided);
1276
1281
  const producedSoFar = /* @__PURE__ */ new Set();
1277
- const waiting = new Set(__privateGet$7(this, _nodes).values());
1282
+ const waiting = new Set(__privateGet$8(this, _nodes).values());
1278
1283
  const visited = /* @__PURE__ */ new Set();
1279
1284
  const results = new Array();
1280
1285
  let inFlight = 0;
@@ -1320,26 +1325,26 @@ _nodes = new WeakMap();
1320
1325
  _allProvided = new WeakMap();
1321
1326
  let DependencyGraph = _DependencyGraph;
1322
1327
 
1323
- var __accessCheck$7 = (obj, member, msg) => {
1328
+ var __accessCheck$9 = (obj, member, msg) => {
1324
1329
  if (!member.has(obj))
1325
1330
  throw TypeError("Cannot " + msg);
1326
1331
  };
1327
- var __privateGet$6 = (obj, member, getter) => {
1328
- __accessCheck$7(obj, member, "read from private field");
1329
- return getter ? getter.call(obj) : member.get(obj);
1332
+ var __privateGet$7 = (obj, member, getter) => {
1333
+ __accessCheck$9(obj, member, "read from private field");
1334
+ return member.get(obj);
1330
1335
  };
1331
- var __privateAdd$7 = (obj, member, value) => {
1336
+ var __privateAdd$9 = (obj, member, value) => {
1332
1337
  if (member.has(obj))
1333
1338
  throw TypeError("Cannot add the same private member more than once");
1334
1339
  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1335
1340
  };
1336
- var __privateSet$6 = (obj, member, value, setter) => {
1337
- __accessCheck$7(obj, member, "write to private field");
1338
- setter ? setter.call(obj, value) : member.set(obj, value);
1341
+ var __privateSet$5 = (obj, member, value, setter) => {
1342
+ __accessCheck$9(obj, member, "write to private field");
1343
+ member.set(obj, value);
1339
1344
  return value;
1340
1345
  };
1341
- var __privateMethod$5 = (obj, member, method) => {
1342
- __accessCheck$7(obj, member, "access private method");
1346
+ var __privateMethod$6 = (obj, member, method) => {
1347
+ __accessCheck$9(obj, member, "access private method");
1343
1348
  return method;
1344
1349
  };
1345
1350
  var _providedFactories, _loadedDefaultFactories, _implementations, _rootServiceImplementations, _addedFactoryIds, _instantiatedFactories, _resolveFactory, resolveFactory_fn, _checkForMissingDeps, checkForMissingDeps_fn;
@@ -1362,19 +1367,19 @@ const pluginMetadataServiceFactory = backendPluginApi.createServiceFactory(
1362
1367
  );
1363
1368
  const _ServiceRegistry = class _ServiceRegistry {
1364
1369
  constructor(factories) {
1365
- __privateAdd$7(this, _resolveFactory);
1366
- __privateAdd$7(this, _checkForMissingDeps);
1367
- __privateAdd$7(this, _providedFactories, void 0);
1368
- __privateAdd$7(this, _loadedDefaultFactories, void 0);
1369
- __privateAdd$7(this, _implementations, void 0);
1370
- __privateAdd$7(this, _rootServiceImplementations, /* @__PURE__ */ new Map());
1371
- __privateAdd$7(this, _addedFactoryIds, /* @__PURE__ */ new Set());
1372
- __privateAdd$7(this, _instantiatedFactories, /* @__PURE__ */ new Set());
1373
- __privateSet$6(this, _providedFactories, new Map(
1370
+ __privateAdd$9(this, _resolveFactory);
1371
+ __privateAdd$9(this, _checkForMissingDeps);
1372
+ __privateAdd$9(this, _providedFactories, void 0);
1373
+ __privateAdd$9(this, _loadedDefaultFactories, void 0);
1374
+ __privateAdd$9(this, _implementations, void 0);
1375
+ __privateAdd$9(this, _rootServiceImplementations, /* @__PURE__ */ new Map());
1376
+ __privateAdd$9(this, _addedFactoryIds, /* @__PURE__ */ new Set());
1377
+ __privateAdd$9(this, _instantiatedFactories, /* @__PURE__ */ new Set());
1378
+ __privateSet$5(this, _providedFactories, new Map(
1374
1379
  factories.map((sf) => [sf.service.id, toInternalServiceFactory(sf)])
1375
1380
  ));
1376
- __privateSet$6(this, _loadedDefaultFactories, /* @__PURE__ */ new Map());
1377
- __privateSet$6(this, _implementations, /* @__PURE__ */ new Map());
1381
+ __privateSet$5(this, _loadedDefaultFactories, /* @__PURE__ */ new Map());
1382
+ __privateSet$5(this, _implementations, /* @__PURE__ */ new Map());
1378
1383
  }
1379
1384
  static create(factories) {
1380
1385
  const registry = new _ServiceRegistry(factories);
@@ -1383,7 +1388,7 @@ const _ServiceRegistry = class _ServiceRegistry {
1383
1388
  }
1384
1389
  checkForCircularDeps() {
1385
1390
  const graph = DependencyGraph.fromIterable(
1386
- Array.from(__privateGet$6(this, _providedFactories)).map(
1391
+ Array.from(__privateGet$7(this, _providedFactories)).map(
1387
1392
  ([serviceId, serviceFactory]) => ({
1388
1393
  value: serviceId,
1389
1394
  provides: [serviceId],
@@ -1405,21 +1410,21 @@ const _ServiceRegistry = class _ServiceRegistry {
1405
1410
  `The ${backendPluginApi.coreServices.pluginMetadata.id} service cannot be overridden`
1406
1411
  );
1407
1412
  }
1408
- if (__privateGet$6(this, _addedFactoryIds).has(factoryId)) {
1413
+ if (__privateGet$7(this, _addedFactoryIds).has(factoryId)) {
1409
1414
  throw new Error(
1410
1415
  `Duplicate service implementations provided for ${factoryId}`
1411
1416
  );
1412
1417
  }
1413
- if (__privateGet$6(this, _instantiatedFactories).has(factoryId)) {
1418
+ if (__privateGet$7(this, _instantiatedFactories).has(factoryId)) {
1414
1419
  throw new Error(
1415
1420
  `Unable to set service factory with id ${factoryId}, service has already been instantiated`
1416
1421
  );
1417
1422
  }
1418
- __privateGet$6(this, _addedFactoryIds).add(factoryId);
1419
- __privateGet$6(this, _providedFactories).set(factoryId, toInternalServiceFactory(factory));
1423
+ __privateGet$7(this, _addedFactoryIds).add(factoryId);
1424
+ __privateGet$7(this, _providedFactories).set(factoryId, toInternalServiceFactory(factory));
1420
1425
  }
1421
1426
  async initializeEagerServicesWithScope(scope, pluginId = "root") {
1422
- for (const factory of __privateGet$6(this, _providedFactories).values()) {
1427
+ for (const factory of __privateGet$7(this, _providedFactories).values()) {
1423
1428
  if (factory.service.scope === scope) {
1424
1429
  if (scope === "root" && factory.initialization !== "lazy") {
1425
1430
  await this.get(factory.service, pluginId);
@@ -1431,12 +1436,12 @@ const _ServiceRegistry = class _ServiceRegistry {
1431
1436
  }
1432
1437
  get(ref, pluginId) {
1433
1438
  var _a;
1434
- __privateGet$6(this, _instantiatedFactories).add(ref.id);
1435
- return (_a = __privateMethod$5(this, _resolveFactory, resolveFactory_fn).call(this, ref, pluginId)) == null ? void 0 : _a.then((factory) => {
1439
+ __privateGet$7(this, _instantiatedFactories).add(ref.id);
1440
+ return (_a = __privateMethod$6(this, _resolveFactory, resolveFactory_fn).call(this, ref, pluginId)) == null ? void 0 : _a.then((factory) => {
1436
1441
  if (factory.service.scope === "root") {
1437
- let existing = __privateGet$6(this, _rootServiceImplementations).get(factory);
1442
+ let existing = __privateGet$7(this, _rootServiceImplementations).get(factory);
1438
1443
  if (!existing) {
1439
- __privateMethod$5(this, _checkForMissingDeps, checkForMissingDeps_fn).call(this, factory, pluginId);
1444
+ __privateMethod$6(this, _checkForMissingDeps, checkForMissingDeps_fn).call(this, factory, pluginId);
1440
1445
  const rootDeps = new Array();
1441
1446
  for (const [name, serviceRef] of Object.entries(factory.deps)) {
1442
1447
  if (serviceRef.scope !== "root") {
@@ -1450,13 +1455,13 @@ const _ServiceRegistry = class _ServiceRegistry {
1450
1455
  existing = Promise.all(rootDeps).then(
1451
1456
  (entries) => factory.factory(Object.fromEntries(entries), void 0)
1452
1457
  );
1453
- __privateGet$6(this, _rootServiceImplementations).set(factory, existing);
1458
+ __privateGet$7(this, _rootServiceImplementations).set(factory, existing);
1454
1459
  }
1455
1460
  return existing;
1456
1461
  }
1457
- let implementation = __privateGet$6(this, _implementations).get(factory);
1462
+ let implementation = __privateGet$7(this, _implementations).get(factory);
1458
1463
  if (!implementation) {
1459
- __privateMethod$5(this, _checkForMissingDeps, checkForMissingDeps_fn).call(this, factory, pluginId);
1464
+ __privateMethod$6(this, _checkForMissingDeps, checkForMissingDeps_fn).call(this, factory, pluginId);
1460
1465
  const rootDeps = new Array();
1461
1466
  for (const [name, serviceRef] of Object.entries(factory.deps)) {
1462
1467
  if (serviceRef.scope === "root") {
@@ -1478,7 +1483,7 @@ const _ServiceRegistry = class _ServiceRegistry {
1478
1483
  }),
1479
1484
  byPlugin: /* @__PURE__ */ new Map()
1480
1485
  };
1481
- __privateGet$6(this, _implementations).set(factory, implementation);
1486
+ __privateGet$7(this, _implementations).set(factory, implementation);
1482
1487
  }
1483
1488
  let result = implementation.byPlugin.get(pluginId);
1484
1489
  if (!result) {
@@ -1516,18 +1521,18 @@ resolveFactory_fn = function(ref, pluginId) {
1516
1521
  toInternalServiceFactory(pluginMetadataServiceFactory({ pluginId }))
1517
1522
  );
1518
1523
  }
1519
- let resolvedFactory = __privateGet$6(this, _providedFactories).get(ref.id);
1524
+ let resolvedFactory = __privateGet$7(this, _providedFactories).get(ref.id);
1520
1525
  const { __defaultFactory: defaultFactory } = ref;
1521
1526
  if (!resolvedFactory && !defaultFactory) {
1522
1527
  return void 0;
1523
1528
  }
1524
1529
  if (!resolvedFactory) {
1525
- let loadedFactory = __privateGet$6(this, _loadedDefaultFactories).get(defaultFactory);
1530
+ let loadedFactory = __privateGet$7(this, _loadedDefaultFactories).get(defaultFactory);
1526
1531
  if (!loadedFactory) {
1527
1532
  loadedFactory = Promise.resolve().then(() => defaultFactory(ref)).then(
1528
1533
  (f) => toInternalServiceFactory(typeof f === "function" ? f() : f)
1529
1534
  );
1530
- __privateGet$6(this, _loadedDefaultFactories).set(defaultFactory, loadedFactory);
1535
+ __privateGet$7(this, _loadedDefaultFactories).set(defaultFactory, loadedFactory);
1531
1536
  }
1532
1537
  resolvedFactory = loadedFactory.catch((error) => {
1533
1538
  throw new Error(
@@ -1545,7 +1550,7 @@ checkForMissingDeps_fn = function(factory, pluginId) {
1545
1550
  if (ref.id === backendPluginApi.coreServices.pluginMetadata.id) {
1546
1551
  return false;
1547
1552
  }
1548
- if (__privateGet$6(this, _providedFactories).get(ref.id)) {
1553
+ if (__privateGet$7(this, _providedFactories).get(ref.id)) {
1549
1554
  return false;
1550
1555
  }
1551
1556
  return !ref.__defaultFactory;
@@ -1559,52 +1564,52 @@ checkForMissingDeps_fn = function(factory, pluginId) {
1559
1564
  };
1560
1565
  let ServiceRegistry = _ServiceRegistry;
1561
1566
 
1562
- var __accessCheck$6 = (obj, member, msg) => {
1567
+ var __accessCheck$8 = (obj, member, msg) => {
1563
1568
  if (!member.has(obj))
1564
1569
  throw TypeError("Cannot " + msg);
1565
1570
  };
1566
- var __privateGet$5 = (obj, member, getter) => {
1567
- __accessCheck$6(obj, member, "read from private field");
1568
- return getter ? getter.call(obj) : member.get(obj);
1571
+ var __privateGet$6 = (obj, member, getter) => {
1572
+ __accessCheck$8(obj, member, "read from private field");
1573
+ return member.get(obj);
1569
1574
  };
1570
- var __privateAdd$6 = (obj, member, value) => {
1575
+ var __privateAdd$8 = (obj, member, value) => {
1571
1576
  if (member.has(obj))
1572
1577
  throw TypeError("Cannot add the same private member more than once");
1573
1578
  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1574
1579
  };
1575
- var __privateSet$5 = (obj, member, value, setter) => {
1576
- __accessCheck$6(obj, member, "write to private field");
1577
- setter ? setter.call(obj, value) : member.set(obj, value);
1580
+ var __privateSet$4 = (obj, member, value, setter) => {
1581
+ __accessCheck$8(obj, member, "write to private field");
1582
+ member.set(obj, value);
1578
1583
  return value;
1579
1584
  };
1580
- var __privateMethod$4 = (obj, member, method) => {
1581
- __accessCheck$6(obj, member, "access private method");
1585
+ var __privateMethod$5 = (obj, member, method) => {
1586
+ __accessCheck$8(obj, member, "access private method");
1582
1587
  return method;
1583
1588
  };
1584
1589
  var _startPromise, _features, _extensionPoints, _serviceRegistry, _registeredFeatures, _getInitDeps, getInitDeps_fn, _addFeature, addFeature_fn, _doStart, doStart_fn, _getRootLifecycleImpl, getRootLifecycleImpl_fn, _getPluginLifecycleImpl, getPluginLifecycleImpl_fn;
1585
1590
  class BackendInitializer {
1586
1591
  constructor(defaultApiFactories) {
1587
- __privateAdd$6(this, _getInitDeps);
1588
- __privateAdd$6(this, _addFeature);
1589
- __privateAdd$6(this, _doStart);
1592
+ __privateAdd$8(this, _getInitDeps);
1593
+ __privateAdd$8(this, _addFeature);
1594
+ __privateAdd$8(this, _doStart);
1590
1595
  // Bit of a hacky way to grab the lifecycle services, potentially find a nicer way to do this
1591
- __privateAdd$6(this, _getRootLifecycleImpl);
1592
- __privateAdd$6(this, _getPluginLifecycleImpl);
1593
- __privateAdd$6(this, _startPromise, void 0);
1594
- __privateAdd$6(this, _features, new Array());
1595
- __privateAdd$6(this, _extensionPoints, /* @__PURE__ */ new Map());
1596
- __privateAdd$6(this, _serviceRegistry, void 0);
1597
- __privateAdd$6(this, _registeredFeatures, new Array());
1598
- __privateSet$5(this, _serviceRegistry, ServiceRegistry.create([...defaultApiFactories]));
1596
+ __privateAdd$8(this, _getRootLifecycleImpl);
1597
+ __privateAdd$8(this, _getPluginLifecycleImpl);
1598
+ __privateAdd$8(this, _startPromise, void 0);
1599
+ __privateAdd$8(this, _features, new Array());
1600
+ __privateAdd$8(this, _extensionPoints, /* @__PURE__ */ new Map());
1601
+ __privateAdd$8(this, _serviceRegistry, void 0);
1602
+ __privateAdd$8(this, _registeredFeatures, new Array());
1603
+ __privateSet$4(this, _serviceRegistry, ServiceRegistry.create([...defaultApiFactories]));
1599
1604
  }
1600
1605
  add(feature) {
1601
- if (__privateGet$5(this, _startPromise)) {
1606
+ if (__privateGet$6(this, _startPromise)) {
1602
1607
  throw new Error("feature can not be added after the backend has started");
1603
1608
  }
1604
- __privateGet$5(this, _registeredFeatures).push(Promise.resolve(feature));
1609
+ __privateGet$6(this, _registeredFeatures).push(Promise.resolve(feature));
1605
1610
  }
1606
1611
  async start() {
1607
- if (__privateGet$5(this, _startPromise)) {
1612
+ if (__privateGet$6(this, _startPromise)) {
1608
1613
  throw new Error("Backend has already started");
1609
1614
  }
1610
1615
  const exitHandler = async () => {
@@ -1622,18 +1627,18 @@ class BackendInitializer {
1622
1627
  process.addListener("SIGTERM", exitHandler);
1623
1628
  process.addListener("SIGINT", exitHandler);
1624
1629
  process.addListener("beforeExit", exitHandler);
1625
- __privateSet$5(this, _startPromise, __privateMethod$4(this, _doStart, doStart_fn).call(this));
1626
- await __privateGet$5(this, _startPromise);
1630
+ __privateSet$4(this, _startPromise, __privateMethod$5(this, _doStart, doStart_fn).call(this));
1631
+ await __privateGet$6(this, _startPromise);
1627
1632
  }
1628
1633
  async stop() {
1629
- if (!__privateGet$5(this, _startPromise)) {
1634
+ if (!__privateGet$6(this, _startPromise)) {
1630
1635
  return;
1631
1636
  }
1632
1637
  try {
1633
- await __privateGet$5(this, _startPromise);
1638
+ await __privateGet$6(this, _startPromise);
1634
1639
  } catch (error) {
1635
1640
  }
1636
- const lifecycleService = await __privateMethod$4(this, _getRootLifecycleImpl, getRootLifecycleImpl_fn).call(this);
1641
+ const lifecycleService = await __privateMethod$5(this, _getRootLifecycleImpl, getRootLifecycleImpl_fn).call(this);
1637
1642
  await lifecycleService.shutdown();
1638
1643
  }
1639
1644
  }
@@ -1647,7 +1652,7 @@ getInitDeps_fn = async function(deps, pluginId, moduleId) {
1647
1652
  const result = /* @__PURE__ */ new Map();
1648
1653
  const missingRefs = /* @__PURE__ */ new Set();
1649
1654
  for (const [name, ref] of Object.entries(deps)) {
1650
- const ep = __privateGet$5(this, _extensionPoints).get(ref.id);
1655
+ const ep = __privateGet$6(this, _extensionPoints).get(ref.id);
1651
1656
  if (ep) {
1652
1657
  if (ep.pluginId !== pluginId) {
1653
1658
  throw new Error(
@@ -1656,7 +1661,7 @@ getInitDeps_fn = async function(deps, pluginId, moduleId) {
1656
1661
  }
1657
1662
  result.set(name, ep.impl);
1658
1663
  } else {
1659
- const impl = await __privateGet$5(this, _serviceRegistry).get(
1664
+ const impl = await __privateGet$6(this, _serviceRegistry).get(
1660
1665
  ref,
1661
1666
  pluginId
1662
1667
  );
@@ -1683,14 +1688,14 @@ addFeature_fn = function(feature) {
1683
1688
  );
1684
1689
  }
1685
1690
  if (isServiceFactory(feature)) {
1686
- __privateGet$5(this, _serviceRegistry).add(feature);
1691
+ __privateGet$6(this, _serviceRegistry).add(feature);
1687
1692
  } else if (isInternalBackendFeature(feature)) {
1688
1693
  if (feature.version !== "v1") {
1689
1694
  throw new Error(
1690
1695
  `Failed to add feature, invalid version '${feature.version}'`
1691
1696
  );
1692
1697
  }
1693
- __privateGet$5(this, _features).push(feature);
1698
+ __privateGet$6(this, _features).push(feature);
1694
1699
  } else {
1695
1700
  throw new Error(
1696
1701
  `Failed to add feature, invalid feature ${JSON.stringify(feature)}`
@@ -1699,35 +1704,35 @@ addFeature_fn = function(feature) {
1699
1704
  };
1700
1705
  _doStart = new WeakSet();
1701
1706
  doStart_fn = async function() {
1702
- __privateGet$5(this, _serviceRegistry).checkForCircularDeps();
1703
- for (const feature of __privateGet$5(this, _registeredFeatures)) {
1704
- __privateMethod$4(this, _addFeature, addFeature_fn).call(this, await feature);
1707
+ __privateGet$6(this, _serviceRegistry).checkForCircularDeps();
1708
+ for (const feature of __privateGet$6(this, _registeredFeatures)) {
1709
+ __privateMethod$5(this, _addFeature, addFeature_fn).call(this, await feature);
1705
1710
  }
1706
- const featureDiscovery = await __privateGet$5(this, _serviceRegistry).get(
1711
+ const featureDiscovery = await __privateGet$6(this, _serviceRegistry).get(
1707
1712
  alpha.featureDiscoveryServiceRef,
1708
1713
  "root"
1709
1714
  );
1710
1715
  if (featureDiscovery) {
1711
1716
  const { features } = await featureDiscovery.getBackendFeatures();
1712
1717
  for (const feature of features) {
1713
- __privateMethod$4(this, _addFeature, addFeature_fn).call(this, feature);
1718
+ __privateMethod$5(this, _addFeature, addFeature_fn).call(this, feature);
1714
1719
  }
1715
- __privateGet$5(this, _serviceRegistry).checkForCircularDeps();
1720
+ __privateGet$6(this, _serviceRegistry).checkForCircularDeps();
1716
1721
  }
1717
- await __privateGet$5(this, _serviceRegistry).initializeEagerServicesWithScope("root");
1722
+ await __privateGet$6(this, _serviceRegistry).initializeEagerServicesWithScope("root");
1718
1723
  const pluginInits = /* @__PURE__ */ new Map();
1719
1724
  const moduleInits = /* @__PURE__ */ new Map();
1720
- for (const feature of __privateGet$5(this, _features)) {
1725
+ for (const feature of __privateGet$6(this, _features)) {
1721
1726
  for (const r of feature.getRegistrations()) {
1722
1727
  const provides = /* @__PURE__ */ new Set();
1723
1728
  if (r.type === "plugin" || r.type === "module") {
1724
1729
  for (const [extRef, extImpl] of r.extensionPoints) {
1725
- if (__privateGet$5(this, _extensionPoints).has(extRef.id)) {
1730
+ if (__privateGet$6(this, _extensionPoints).has(extRef.id)) {
1726
1731
  throw new Error(
1727
1732
  `ExtensionPoint with ID '${extRef.id}' is already registered`
1728
1733
  );
1729
1734
  }
1730
- __privateGet$5(this, _extensionPoints).set(extRef.id, {
1735
+ __privateGet$6(this, _extensionPoints).set(extRef.id, {
1731
1736
  impl: extImpl,
1732
1737
  pluginId: r.pluginId
1733
1738
  });
@@ -1765,7 +1770,7 @@ doStart_fn = async function() {
1765
1770
  const allPluginIds = [...pluginInits.keys()];
1766
1771
  await Promise.all(
1767
1772
  allPluginIds.map(async (pluginId) => {
1768
- await __privateGet$5(this, _serviceRegistry).initializeEagerServicesWithScope(
1773
+ await __privateGet$6(this, _serviceRegistry).initializeEagerServicesWithScope(
1769
1774
  "plugin",
1770
1775
  pluginId
1771
1776
  );
@@ -1789,7 +1794,7 @@ doStart_fn = async function() {
1789
1794
  }
1790
1795
  await tree.parallelTopologicalTraversal(
1791
1796
  async ({ moduleId, moduleInit }) => {
1792
- const moduleDeps = await __privateMethod$4(this, _getInitDeps, getInitDeps_fn).call(this, moduleInit.init.deps, pluginId, moduleId);
1797
+ const moduleDeps = await __privateMethod$5(this, _getInitDeps, getInitDeps_fn).call(this, moduleInit.init.deps, pluginId, moduleId);
1793
1798
  await moduleInit.init.func(moduleDeps).catch((error) => {
1794
1799
  throw new errors.ForwardedError(
1795
1800
  `Module '${moduleId}' for plugin '${pluginId}' startup failed`,
@@ -1801,7 +1806,7 @@ doStart_fn = async function() {
1801
1806
  }
1802
1807
  const pluginInit = pluginInits.get(pluginId);
1803
1808
  if (pluginInit) {
1804
- const pluginDeps = await __privateMethod$4(this, _getInitDeps, getInitDeps_fn).call(this, pluginInit.init.deps, pluginId);
1809
+ const pluginDeps = await __privateMethod$5(this, _getInitDeps, getInitDeps_fn).call(this, pluginInit.init.deps, pluginId);
1805
1810
  await pluginInit.init.func(pluginDeps).catch((error) => {
1806
1811
  throw new errors.ForwardedError(
1807
1812
  `Plugin '${pluginId}' startup failed`,
@@ -1809,14 +1814,14 @@ doStart_fn = async function() {
1809
1814
  );
1810
1815
  });
1811
1816
  }
1812
- const lifecycleService2 = await __privateMethod$4(this, _getPluginLifecycleImpl, getPluginLifecycleImpl_fn).call(this, pluginId);
1817
+ const lifecycleService2 = await __privateMethod$5(this, _getPluginLifecycleImpl, getPluginLifecycleImpl_fn).call(this, pluginId);
1813
1818
  await lifecycleService2.startup();
1814
1819
  })
1815
1820
  );
1816
- const lifecycleService = await __privateMethod$4(this, _getRootLifecycleImpl, getRootLifecycleImpl_fn).call(this);
1821
+ const lifecycleService = await __privateMethod$5(this, _getRootLifecycleImpl, getRootLifecycleImpl_fn).call(this);
1817
1822
  await lifecycleService.startup();
1818
1823
  if (process.env.NODE_ENV !== "test") {
1819
- const rootLogger = await __privateGet$5(this, _serviceRegistry).get(
1824
+ const rootLogger = await __privateGet$6(this, _serviceRegistry).get(
1820
1825
  backendPluginApi.coreServices.rootLogger,
1821
1826
  "root"
1822
1827
  );
@@ -1832,7 +1837,7 @@ doStart_fn = async function() {
1832
1837
  };
1833
1838
  _getRootLifecycleImpl = new WeakSet();
1834
1839
  getRootLifecycleImpl_fn = async function() {
1835
- const lifecycleService = await __privateGet$5(this, _serviceRegistry).get(
1840
+ const lifecycleService = await __privateGet$6(this, _serviceRegistry).get(
1836
1841
  backendPluginApi.coreServices.rootLifecycle,
1837
1842
  "root"
1838
1843
  );
@@ -1843,7 +1848,7 @@ getRootLifecycleImpl_fn = async function() {
1843
1848
  };
1844
1849
  _getPluginLifecycleImpl = new WeakSet();
1845
1850
  getPluginLifecycleImpl_fn = async function(pluginId) {
1846
- const lifecycleService = await __privateGet$5(this, _serviceRegistry).get(
1851
+ const lifecycleService = await __privateGet$6(this, _serviceRegistry).get(
1847
1852
  backendPluginApi.coreServices.lifecycle,
1848
1853
  pluginId
1849
1854
  );
@@ -1859,42 +1864,42 @@ function isInternalBackendFeature(feature) {
1859
1864
  return typeof feature.getRegistrations === "function";
1860
1865
  }
1861
1866
 
1862
- var __accessCheck$5 = (obj, member, msg) => {
1867
+ var __accessCheck$7 = (obj, member, msg) => {
1863
1868
  if (!member.has(obj))
1864
1869
  throw TypeError("Cannot " + msg);
1865
1870
  };
1866
- var __privateGet$4 = (obj, member, getter) => {
1867
- __accessCheck$5(obj, member, "read from private field");
1868
- return getter ? getter.call(obj) : member.get(obj);
1871
+ var __privateGet$5 = (obj, member, getter) => {
1872
+ __accessCheck$7(obj, member, "read from private field");
1873
+ return member.get(obj);
1869
1874
  };
1870
- var __privateAdd$5 = (obj, member, value) => {
1875
+ var __privateAdd$7 = (obj, member, value) => {
1871
1876
  if (member.has(obj))
1872
1877
  throw TypeError("Cannot add the same private member more than once");
1873
1878
  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1874
1879
  };
1875
- var __privateSet$4 = (obj, member, value, setter) => {
1876
- __accessCheck$5(obj, member, "write to private field");
1877
- setter ? setter.call(obj, value) : member.set(obj, value);
1880
+ var __privateSet$3 = (obj, member, value, setter) => {
1881
+ __accessCheck$7(obj, member, "write to private field");
1882
+ member.set(obj, value);
1878
1883
  return value;
1879
1884
  };
1880
1885
  var _initializer;
1881
1886
  class BackstageBackend {
1882
1887
  constructor(defaultServiceFactories) {
1883
- __privateAdd$5(this, _initializer, void 0);
1884
- __privateSet$4(this, _initializer, new BackendInitializer(defaultServiceFactories));
1888
+ __privateAdd$7(this, _initializer, void 0);
1889
+ __privateSet$3(this, _initializer, new BackendInitializer(defaultServiceFactories));
1885
1890
  }
1886
1891
  add(feature) {
1887
1892
  if (isPromise(feature)) {
1888
- __privateGet$4(this, _initializer).add(feature.then((f) => unwrapFeature(f.default)));
1893
+ __privateGet$5(this, _initializer).add(feature.then((f) => unwrapFeature(f.default)));
1889
1894
  } else {
1890
- __privateGet$4(this, _initializer).add(unwrapFeature(feature));
1895
+ __privateGet$5(this, _initializer).add(unwrapFeature(feature));
1891
1896
  }
1892
1897
  }
1893
1898
  async start() {
1894
- await __privateGet$4(this, _initializer).start();
1899
+ await __privateGet$5(this, _initializer).start();
1895
1900
  }
1896
1901
  async stop() {
1897
- await __privateGet$4(this, _initializer).stop();
1902
+ await __privateGet$5(this, _initializer).stop();
1898
1903
  }
1899
1904
  }
1900
1905
  _initializer = new WeakMap();
@@ -1940,199 +1945,327 @@ function createSpecializedBackend(options) {
1940
1945
  return new BackstageBackend(services);
1941
1946
  }
1942
1947
 
1943
- var __accessCheck$4 = (obj, member, msg) => {
1944
- if (!member.has(obj))
1945
- throw TypeError("Cannot " + msg);
1946
- };
1947
- var __privateGet$3 = (obj, member, getter) => {
1948
- __accessCheck$4(obj, member, "read from private field");
1949
- return getter ? getter.call(obj) : member.get(obj);
1950
- };
1951
- var __privateAdd$4 = (obj, member, value) => {
1952
- if (member.has(obj))
1953
- throw TypeError("Cannot add the same private member more than once");
1954
- member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
1955
- };
1956
- var __privateSet$3 = (obj, member, value, setter) => {
1957
- __accessCheck$4(obj, member, "write to private field");
1958
- setter ? setter.call(obj, value) : member.set(obj, value);
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);
1948
+ const MIGRATIONS_TABLE = "backstage_backend_public_keys__knex_migrations";
1949
+ const TABLE = "backstage_backend_public_keys__keys";
1950
+ function applyDatabaseMigrations(knex) {
1951
+ const migrationsDir = backendCommon.resolvePackagePath(
1952
+ "@backstage/backend-app-api",
1953
+ "migrations"
1954
+ );
1955
+ return knex.migrate.latest({
1956
+ directory: migrationsDir,
1957
+ tableName: MIGRATIONS_TABLE
1958
+ });
1959
+ }
1960
+ class DatabaseKeyStore {
1961
+ constructor(client, logger) {
1962
+ this.client = client;
1963
+ this.logger = logger;
1968
1964
  }
1969
- get getKey() {
1970
- if (!__privateGet$3(this, _keyStore)) {
1971
- throw new errors.AuthenticationError(
1972
- "refreshKeyStore must be called before jwksClient.getKey"
1973
- );
1965
+ static async create(options) {
1966
+ var _a;
1967
+ const { database, logger } = options;
1968
+ const client = await database.getClient();
1969
+ if (!((_a = database.migrations) == null ? void 0 : _a.skip)) {
1970
+ await applyDatabaseMigrations(client);
1974
1971
  }
1975
- return __privateGet$3(this, _keyStore);
1972
+ return new DatabaseKeyStore(client, logger);
1976
1973
  }
1977
- /**
1978
- * If the last keystore refresh is stale, update the keystore URL to the latest
1979
- */
1980
- async refreshKeyStore(rawJwtToken) {
1981
- const payload = await jose.decodeJwt(rawJwtToken);
1982
- const header = await jose.decodeProtectedHeader(rawJwtToken);
1983
- let keyStoreHasKey;
1984
- try {
1985
- if (__privateGet$3(this, _keyStore)) {
1986
- const [_, rawPayload, rawSignature] = rawJwtToken.split(".");
1987
- keyStoreHasKey = await __privateGet$3(this, _keyStore).call(this, header, {
1988
- payload: rawPayload,
1989
- signature: rawSignature
1990
- });
1974
+ async addKey(options) {
1975
+ await this.client(TABLE).insert({
1976
+ id: options.key.kid,
1977
+ key: JSON.stringify(options.key),
1978
+ expires_at: options.expiresAt.toISOString()
1979
+ });
1980
+ }
1981
+ async listKeys() {
1982
+ const rows = await this.client(TABLE).select();
1983
+ const keys = rows.map((row) => ({
1984
+ id: row.id,
1985
+ key: JSON.parse(row.key),
1986
+ expiresAt: new Date(row.expires_at)
1987
+ }));
1988
+ const validKeys = [];
1989
+ const expiredKeys = [];
1990
+ for (const key of keys) {
1991
+ if (luxon.DateTime.fromJSDate(key.expiresAt) < luxon.DateTime.local()) {
1992
+ expiredKeys.push(key);
1993
+ } else {
1994
+ validKeys.push(key);
1991
1995
  }
1992
- } catch (error) {
1993
- keyStoreHasKey = false;
1994
1996
  }
1995
- const issuedAfterLastRefresh = (payload == null ? void 0 : payload.iat) && payload.iat > __privateGet$3(this, _keyStoreUpdated) - CLOCK_MARGIN_S;
1996
- if (!__privateGet$3(this, _keyStore) || !keyStoreHasKey && issuedAfterLastRefresh) {
1997
- const endpoint = await this.getEndpoint();
1998
- __privateSet$3(this, _keyStore, jose.createRemoteJWKSet(endpoint));
1999
- __privateSet$3(this, _keyStoreUpdated, Date.now() / 1e3);
1997
+ if (expiredKeys.length > 0) {
1998
+ const kids = expiredKeys.map(({ key }) => key.kid);
1999
+ this.logger.info(
2000
+ `Removing expired plugin service keys, '${kids.join("', '")}'`
2001
+ );
2002
+ this.client(TABLE).delete().whereIn("id", kids).catch((error) => {
2003
+ this.logger.error(
2004
+ "Failed to remove expired plugin service keys",
2005
+ error
2006
+ );
2007
+ });
2000
2008
  }
2009
+ return { keys: validKeys };
2001
2010
  }
2002
2011
  }
2003
- _keyStore = new WeakMap();
2004
- _keyStoreUpdated = new WeakMap();
2005
2012
 
2006
- var __accessCheck$3 = (obj, member, msg) => {
2013
+ function createCredentialsWithServicePrincipal(sub, token) {
2014
+ return {
2015
+ $$type: "@backstage/BackstageCredentials",
2016
+ version: "v1",
2017
+ token,
2018
+ principal: {
2019
+ type: "service",
2020
+ subject: sub
2021
+ }
2022
+ };
2023
+ }
2024
+ function createCredentialsWithUserPrincipal(sub, token, expiresAt) {
2025
+ return {
2026
+ $$type: "@backstage/BackstageCredentials",
2027
+ version: "v1",
2028
+ token,
2029
+ expiresAt,
2030
+ principal: {
2031
+ type: "user",
2032
+ userEntityRef: sub
2033
+ }
2034
+ };
2035
+ }
2036
+ function createCredentialsWithNonePrincipal() {
2037
+ return {
2038
+ $$type: "@backstage/BackstageCredentials",
2039
+ version: "v1",
2040
+ principal: {
2041
+ type: "none"
2042
+ }
2043
+ };
2044
+ }
2045
+ function toInternalBackstageCredentials(credentials) {
2046
+ if (credentials.$$type !== "@backstage/BackstageCredentials") {
2047
+ throw new Error("Invalid credential type");
2048
+ }
2049
+ const internalCredentials = credentials;
2050
+ if (internalCredentials.version !== "v1") {
2051
+ throw new Error(
2052
+ `Invalid credential version ${internalCredentials.version}`
2053
+ );
2054
+ }
2055
+ return internalCredentials;
2056
+ }
2057
+
2058
+ var __accessCheck$6 = (obj, member, msg) => {
2007
2059
  if (!member.has(obj))
2008
2060
  throw TypeError("Cannot " + msg);
2009
2061
  };
2010
- var __privateGet$2 = (obj, member, getter) => {
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) => {
2062
+ var __privateAdd$6 = (obj, member, value) => {
2015
2063
  if (member.has(obj))
2016
2064
  throw TypeError("Cannot add the same private member more than once");
2017
2065
  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
2018
2066
  };
2019
- var __privateSet$2 = (obj, member, value, setter) => {
2020
- __accessCheck$3(obj, member, "write to private field");
2021
- setter ? setter.call(obj, value) : member.set(obj, value);
2022
- return value;
2023
- };
2024
- var __privateMethod$3 = (obj, member, method) => {
2025
- __accessCheck$3(obj, member, "access private method");
2067
+ var __privateMethod$4 = (obj, member, method) => {
2068
+ __accessCheck$6(obj, member, "access private method");
2026
2069
  return method;
2027
2070
  };
2028
- var _jwksClient, _algorithms, _getTokenVerificationOptions, getTokenVerificationOptions_fn;
2029
- class UserTokenHandler {
2030
- constructor(options) {
2031
- __privateAdd$3(this, _getTokenVerificationOptions);
2032
- __privateAdd$3(this, _jwksClient, void 0);
2033
- __privateAdd$3(this, _algorithms, void 0);
2034
- __privateSet$2(this, _algorithms, ["ES256"]);
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
- }));
2071
+ var _getJwtExpiration, getJwtExpiration_fn;
2072
+ class DefaultAuthService {
2073
+ constructor(userTokenHandler, pluginTokenHandler, externalTokenHandler, tokenManager, pluginId, disableDefaultAuthPolicy, publicKeyStore) {
2074
+ this.userTokenHandler = userTokenHandler;
2075
+ this.pluginTokenHandler = pluginTokenHandler;
2076
+ this.externalTokenHandler = externalTokenHandler;
2077
+ this.tokenManager = tokenManager;
2078
+ this.pluginId = pluginId;
2079
+ this.disableDefaultAuthPolicy = disableDefaultAuthPolicy;
2080
+ this.publicKeyStore = publicKeyStore;
2081
+ __privateAdd$6(this, _getJwtExpiration);
2039
2082
  }
2040
- async verifyToken(token) {
2041
- const verifyOpts = __privateMethod$3(this, _getTokenVerificationOptions, getTokenVerificationOptions_fn).call(this, token);
2042
- if (!verifyOpts) {
2043
- return void 0;
2083
+ // allowLimitedAccess is currently ignored, since we currently always use the full user tokens
2084
+ async authenticate(token) {
2085
+ const pluginResult = await this.pluginTokenHandler.verifyToken(token);
2086
+ if (pluginResult) {
2087
+ if (pluginResult.limitedUserToken) {
2088
+ const userResult2 = await this.userTokenHandler.verifyToken(
2089
+ pluginResult.limitedUserToken
2090
+ );
2091
+ if (!userResult2) {
2092
+ throw new errors.AuthenticationError(
2093
+ "Invalid user token in plugin token obo claim"
2094
+ );
2095
+ }
2096
+ return createCredentialsWithUserPrincipal(
2097
+ userResult2.userEntityRef,
2098
+ pluginResult.limitedUserToken,
2099
+ __privateMethod$4(this, _getJwtExpiration, getJwtExpiration_fn).call(this, pluginResult.limitedUserToken)
2100
+ );
2101
+ }
2102
+ return createCredentialsWithServicePrincipal(pluginResult.subject);
2044
2103
  }
2045
- await __privateGet$2(this, _jwksClient).refreshKeyStore(token);
2046
- const { payload } = await jose.jwtVerify(
2047
- token,
2048
- __privateGet$2(this, _jwksClient).getKey,
2049
- verifyOpts
2050
- ).catch((e) => {
2051
- throw new errors.AuthenticationError("Invalid token", e);
2052
- });
2053
- const userEntityRef = payload.sub;
2054
- if (!userEntityRef) {
2055
- throw new errors.AuthenticationError("No user sub found in token");
2104
+ const userResult = await this.userTokenHandler.verifyToken(token);
2105
+ if (userResult) {
2106
+ return createCredentialsWithUserPrincipal(
2107
+ userResult.userEntityRef,
2108
+ token,
2109
+ __privateMethod$4(this, _getJwtExpiration, getJwtExpiration_fn).call(this, token)
2110
+ );
2056
2111
  }
2057
- return { userEntityRef };
2112
+ const externalResult = await this.externalTokenHandler.verifyToken(token);
2113
+ if (externalResult) {
2114
+ return createCredentialsWithServicePrincipal(externalResult.subject);
2115
+ }
2116
+ throw new errors.AuthenticationError("Illegal token");
2058
2117
  }
2059
- createLimitedUserToken(backstageToken) {
2060
- const [headerRaw, payloadRaw] = backstageToken.split(".");
2061
- const header = JSON.parse(
2062
- new TextDecoder().decode(jose.base64url.decode(headerRaw))
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) };
2118
+ isPrincipal(credentials, type) {
2119
+ const principal = credentials.principal;
2120
+ if (type === "unknown") {
2121
+ return true;
2070
2122
  }
2071
- if (tokenType !== pluginAuthNode.tokenTypes.user.typParam) {
2123
+ if (principal.type !== type) {
2124
+ return false;
2125
+ }
2126
+ return true;
2127
+ }
2128
+ async getNoneCredentials() {
2129
+ return createCredentialsWithNonePrincipal();
2130
+ }
2131
+ async getOwnServiceCredentials() {
2132
+ return createCredentialsWithServicePrincipal(`plugin:${this.pluginId}`);
2133
+ }
2134
+ async getPluginRequestToken(options) {
2135
+ const { targetPluginId } = options;
2136
+ const internalForward = toInternalBackstageCredentials(options.onBehalfOf);
2137
+ const { type } = internalForward.principal;
2138
+ if (type === "none" && this.disableDefaultAuthPolicy) {
2139
+ return { token: "" };
2140
+ }
2141
+ const targetSupportsNewAuth = await this.pluginTokenHandler.isTargetPluginSupported(targetPluginId);
2142
+ switch (type) {
2143
+ case "service":
2144
+ if (targetSupportsNewAuth) {
2145
+ return this.pluginTokenHandler.issueToken({
2146
+ pluginId: this.pluginId,
2147
+ targetPluginId
2148
+ });
2149
+ }
2150
+ return this.tokenManager.getToken().catch((error) => {
2151
+ throw new errors.ForwardedError(
2152
+ `Unable to generate legacy token for communication with the '${targetPluginId}' plugin. You will typically encounter this error when attempting to call a plugin that does not exist, or is deployed with an old version of Backstage`,
2153
+ error
2154
+ );
2155
+ });
2156
+ case "user": {
2157
+ const { token } = internalForward;
2158
+ if (!token) {
2159
+ throw new Error("User credentials is unexpectedly missing token");
2160
+ }
2161
+ if (targetSupportsNewAuth) {
2162
+ const onBehalfOf = await this.userTokenHandler.createLimitedUserToken(
2163
+ token
2164
+ );
2165
+ return this.pluginTokenHandler.issueToken({
2166
+ pluginId: this.pluginId,
2167
+ targetPluginId,
2168
+ onBehalfOf
2169
+ });
2170
+ }
2171
+ if (this.userTokenHandler.isLimitedUserToken(token)) {
2172
+ throw new errors.AuthenticationError(
2173
+ `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`
2174
+ );
2175
+ }
2176
+ return { token };
2177
+ }
2178
+ default:
2179
+ throw new errors.AuthenticationError(
2180
+ `Refused to issue service token for credential type '${type}'`
2181
+ );
2182
+ }
2183
+ }
2184
+ async getLimitedUserToken(credentials) {
2185
+ const { token: backstageToken } = toInternalBackstageCredentials(credentials);
2186
+ if (!backstageToken) {
2072
2187
  throw new errors.AuthenticationError(
2073
- "Failed to create limited user token, invalid token type"
2188
+ "User credentials is unexpectedly missing token"
2074
2189
  );
2075
2190
  }
2076
- const limitedUserToken = [
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) };
2191
+ return this.userTokenHandler.createLimitedUserToken(backstageToken);
2095
2192
  }
2096
- isLimitedUserToken(token) {
2097
- try {
2098
- const { typ } = jose.decodeProtectedHeader(token);
2099
- return typ === pluginAuthNode.tokenTypes.limitedUser.typParam;
2100
- } catch {
2101
- return false;
2102
- }
2193
+ async listPublicServiceKeys() {
2194
+ const { keys } = await this.publicKeyStore.listKeys();
2195
+ return { keys: keys.map(({ key }) => key) };
2103
2196
  }
2104
2197
  }
2105
- _jwksClient = new WeakMap();
2106
- _algorithms = new WeakMap();
2107
- _getTokenVerificationOptions = new WeakSet();
2108
- getTokenVerificationOptions_fn = function(token) {
2109
- try {
2110
- const { typ } = jose.decodeProtectedHeader(token);
2111
- if (typ === pluginAuthNode.tokenTypes.user.typParam) {
2112
- return {
2113
- algorithms: __privateGet$2(this, _algorithms),
2114
- requiredClaims: ["iat", "exp", "sub"],
2115
- typ: pluginAuthNode.tokenTypes.user.typParam
2116
- };
2198
+ _getJwtExpiration = new WeakSet();
2199
+ getJwtExpiration_fn = function(token) {
2200
+ const { exp } = jose.decodeJwt(token);
2201
+ if (!exp) {
2202
+ throw new errors.AuthenticationError("User token is missing expiration");
2203
+ }
2204
+ return new Date(exp * 1e3);
2205
+ };
2206
+
2207
+ var __accessCheck$5 = (obj, member, msg) => {
2208
+ if (!member.has(obj))
2209
+ throw TypeError("Cannot " + msg);
2210
+ };
2211
+ var __privateGet$4 = (obj, member, getter) => {
2212
+ __accessCheck$5(obj, member, "read from private field");
2213
+ return member.get(obj);
2214
+ };
2215
+ var __privateAdd$5 = (obj, member, value) => {
2216
+ if (member.has(obj))
2217
+ throw TypeError("Cannot add the same private member more than once");
2218
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
2219
+ };
2220
+ var __privateSet$2 = (obj, member, value, setter) => {
2221
+ __accessCheck$5(obj, member, "write to private field");
2222
+ member.set(obj, value);
2223
+ return value;
2224
+ };
2225
+ var _keyStore, _keyStoreUpdated;
2226
+ const CLOCK_MARGIN_S = 10;
2227
+ class JwksClient {
2228
+ constructor(getEndpoint) {
2229
+ this.getEndpoint = getEndpoint;
2230
+ __privateAdd$5(this, _keyStore, void 0);
2231
+ __privateAdd$5(this, _keyStoreUpdated, 0);
2232
+ }
2233
+ get getKey() {
2234
+ if (!__privateGet$4(this, _keyStore)) {
2235
+ throw new errors.AuthenticationError(
2236
+ "refreshKeyStore must be called before jwksClient.getKey"
2237
+ );
2117
2238
  }
2118
- if (typ === pluginAuthNode.tokenTypes.limitedUser.typParam) {
2119
- return {
2120
- algorithms: __privateGet$2(this, _algorithms),
2121
- requiredClaims: ["iat", "exp", "sub"],
2122
- typ: pluginAuthNode.tokenTypes.limitedUser.typParam
2123
- };
2239
+ return __privateGet$4(this, _keyStore);
2240
+ }
2241
+ /**
2242
+ * If the last keystore refresh is stale, update the keystore URL to the latest
2243
+ */
2244
+ async refreshKeyStore(rawJwtToken) {
2245
+ const payload = await jose.decodeJwt(rawJwtToken);
2246
+ const header = await jose.decodeProtectedHeader(rawJwtToken);
2247
+ let keyStoreHasKey;
2248
+ try {
2249
+ if (__privateGet$4(this, _keyStore)) {
2250
+ const [_, rawPayload, rawSignature] = rawJwtToken.split(".");
2251
+ keyStoreHasKey = await __privateGet$4(this, _keyStore).call(this, header, {
2252
+ payload: rawPayload,
2253
+ signature: rawSignature
2254
+ });
2255
+ }
2256
+ } catch (error) {
2257
+ keyStoreHasKey = false;
2124
2258
  }
2125
- const { aud } = jose.decodeJwt(token);
2126
- if (aud === pluginAuthNode.tokenTypes.user.audClaim) {
2127
- return {
2128
- algorithms: __privateGet$2(this, _algorithms),
2129
- audience: pluginAuthNode.tokenTypes.user.audClaim
2130
- };
2259
+ const issuedAfterLastRefresh = (payload == null ? void 0 : payload.iat) && payload.iat > __privateGet$4(this, _keyStoreUpdated) - CLOCK_MARGIN_S;
2260
+ if (!__privateGet$4(this, _keyStore) || !keyStoreHasKey && issuedAfterLastRefresh) {
2261
+ const endpoint = await this.getEndpoint();
2262
+ __privateSet$2(this, _keyStore, jose.createRemoteJWKSet(endpoint));
2263
+ __privateSet$2(this, _keyStoreUpdated, Date.now() / 1e3);
2131
2264
  }
2132
- } catch {
2133
2265
  }
2134
- return void 0;
2135
- };
2266
+ }
2267
+ _keyStore = new WeakMap();
2268
+ _keyStoreUpdated = new WeakMap();
2136
2269
 
2137
2270
  var __defProp = Object.defineProperty;
2138
2271
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -2164,7 +2297,7 @@ class PluginTokenHandler {
2164
2297
  options.logger,
2165
2298
  options.ownPluginId,
2166
2299
  options.publicKeyStore,
2167
- options.keyDurationSeconds,
2300
+ Math.round(types.durationToMilliseconds(options.keyDuration) / 1e3),
2168
2301
  (_a = options.algorithm) != null ? _a : "ES256",
2169
2302
  options.discovery
2170
2303
  );
@@ -2319,258 +2452,298 @@ class PluginTokenHandler {
2319
2452
  }
2320
2453
  }
2321
2454
 
2322
- const MIGRATIONS_TABLE = "backstage_backend_public_keys__knex_migrations";
2323
- const TABLE = "backstage_backend_public_keys__keys";
2324
- function applyDatabaseMigrations(knex) {
2325
- const migrationsDir = backendCommon.resolvePackagePath(
2326
- "@backstage/backend-app-api",
2327
- "migrations"
2328
- );
2329
- return knex.migrate.latest({
2330
- directory: migrationsDir,
2331
- tableName: MIGRATIONS_TABLE
2332
- });
2333
- }
2334
- class DatabaseKeyStore {
2335
- constructor(client, logger) {
2336
- this.client = client;
2337
- this.logger = logger;
2455
+ var __accessCheck$4 = (obj, member, msg) => {
2456
+ if (!member.has(obj))
2457
+ throw TypeError("Cannot " + msg);
2458
+ };
2459
+ var __privateAdd$4 = (obj, member, value) => {
2460
+ if (member.has(obj))
2461
+ throw TypeError("Cannot add the same private member more than once");
2462
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
2463
+ };
2464
+ var __privateMethod$3 = (obj, member, method) => {
2465
+ __accessCheck$4(obj, member, "access private method");
2466
+ return method;
2467
+ };
2468
+ var _getTokenVerificationOptions, getTokenVerificationOptions_fn;
2469
+ const _UserTokenHandler = class _UserTokenHandler {
2470
+ constructor(algorithms, jwksClient) {
2471
+ this.algorithms = algorithms;
2472
+ this.jwksClient = jwksClient;
2473
+ __privateAdd$4(this, _getTokenVerificationOptions);
2474
+ }
2475
+ static create(options) {
2476
+ const algorithms = ["ES256"];
2477
+ const jwksClient = new JwksClient(async () => {
2478
+ const url = await options.discovery.getBaseUrl("auth");
2479
+ return new URL(`${url}/.well-known/jwks.json`);
2480
+ });
2481
+ return new _UserTokenHandler(algorithms, jwksClient);
2482
+ }
2483
+ async verifyToken(token) {
2484
+ const verifyOpts = __privateMethod$3(this, _getTokenVerificationOptions, getTokenVerificationOptions_fn).call(this, token);
2485
+ if (!verifyOpts) {
2486
+ return void 0;
2487
+ }
2488
+ await this.jwksClient.refreshKeyStore(token);
2489
+ const { payload } = await jose.jwtVerify(
2490
+ token,
2491
+ this.jwksClient.getKey,
2492
+ verifyOpts
2493
+ ).catch((e) => {
2494
+ throw new errors.AuthenticationError("Invalid token", e);
2495
+ });
2496
+ const userEntityRef = payload.sub;
2497
+ if (!userEntityRef) {
2498
+ throw new errors.AuthenticationError("No user sub found in token");
2499
+ }
2500
+ return { userEntityRef };
2501
+ }
2502
+ createLimitedUserToken(backstageToken) {
2503
+ const [headerRaw, payloadRaw] = backstageToken.split(".");
2504
+ const header = JSON.parse(
2505
+ new TextDecoder().decode(jose.base64url.decode(headerRaw))
2506
+ );
2507
+ const payload = JSON.parse(
2508
+ new TextDecoder().decode(jose.base64url.decode(payloadRaw))
2509
+ );
2510
+ const tokenType = header.typ;
2511
+ if (!tokenType || tokenType === pluginAuthNode.tokenTypes.limitedUser.typParam) {
2512
+ return { token: backstageToken, expiresAt: new Date(payload.exp * 1e3) };
2513
+ }
2514
+ if (tokenType !== pluginAuthNode.tokenTypes.user.typParam) {
2515
+ throw new errors.AuthenticationError(
2516
+ "Failed to create limited user token, invalid token type"
2517
+ );
2518
+ }
2519
+ const limitedUserToken = [
2520
+ jose.base64url.encode(
2521
+ JSON.stringify({
2522
+ typ: pluginAuthNode.tokenTypes.limitedUser.typParam,
2523
+ alg: header.alg,
2524
+ kid: header.kid
2525
+ })
2526
+ ),
2527
+ jose.base64url.encode(
2528
+ JSON.stringify({
2529
+ sub: payload.sub,
2530
+ ent: payload.ent,
2531
+ iat: payload.iat,
2532
+ exp: payload.exp
2533
+ })
2534
+ ),
2535
+ payload.uip
2536
+ ].join(".");
2537
+ return { token: limitedUserToken, expiresAt: new Date(payload.exp * 1e3) };
2538
+ }
2539
+ isLimitedUserToken(token) {
2540
+ try {
2541
+ const { typ } = jose.decodeProtectedHeader(token);
2542
+ return typ === pluginAuthNode.tokenTypes.limitedUser.typParam;
2543
+ } catch {
2544
+ return false;
2545
+ }
2546
+ }
2547
+ };
2548
+ _getTokenVerificationOptions = new WeakSet();
2549
+ getTokenVerificationOptions_fn = function(token) {
2550
+ try {
2551
+ const { typ } = jose.decodeProtectedHeader(token);
2552
+ if (typ === pluginAuthNode.tokenTypes.user.typParam) {
2553
+ return {
2554
+ algorithms: this.algorithms,
2555
+ requiredClaims: ["iat", "exp", "sub"],
2556
+ typ: pluginAuthNode.tokenTypes.user.typParam
2557
+ };
2558
+ }
2559
+ if (typ === pluginAuthNode.tokenTypes.limitedUser.typParam) {
2560
+ return {
2561
+ algorithms: this.algorithms,
2562
+ requiredClaims: ["iat", "exp", "sub"],
2563
+ typ: pluginAuthNode.tokenTypes.limitedUser.typParam
2564
+ };
2565
+ }
2566
+ const { aud } = jose.decodeJwt(token);
2567
+ if (aud === pluginAuthNode.tokenTypes.user.audClaim) {
2568
+ return {
2569
+ algorithms: this.algorithms,
2570
+ audience: pluginAuthNode.tokenTypes.user.audClaim
2571
+ };
2572
+ }
2573
+ } catch {
2574
+ }
2575
+ return void 0;
2576
+ };
2577
+ let UserTokenHandler = _UserTokenHandler;
2578
+
2579
+ var __accessCheck$3 = (obj, member, msg) => {
2580
+ if (!member.has(obj))
2581
+ throw TypeError("Cannot " + msg);
2582
+ };
2583
+ var __privateGet$3 = (obj, member, getter) => {
2584
+ __accessCheck$3(obj, member, "read from private field");
2585
+ return member.get(obj);
2586
+ };
2587
+ var __privateAdd$3 = (obj, member, value) => {
2588
+ if (member.has(obj))
2589
+ throw TypeError("Cannot add the same private member more than once");
2590
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
2591
+ };
2592
+ var __privateMethod$2 = (obj, member, method) => {
2593
+ __accessCheck$3(obj, member, "access private method");
2594
+ return method;
2595
+ };
2596
+ var _entries$1, _doAdd, doAdd_fn;
2597
+ class LegacyTokenHandler {
2598
+ constructor() {
2599
+ __privateAdd$3(this, _doAdd);
2600
+ __privateAdd$3(this, _entries$1, []);
2338
2601
  }
2339
- static async create(options) {
2340
- var _a;
2341
- const { database, logger } = options;
2342
- const client = await database.getClient();
2343
- if (!((_a = database.migrations) == null ? void 0 : _a.skip)) {
2344
- await applyDatabaseMigrations(client);
2345
- }
2346
- return new DatabaseKeyStore(client, logger);
2602
+ add(options) {
2603
+ __privateMethod$2(this, _doAdd, doAdd_fn).call(this, options.getString("secret"), options.getString("subject"));
2347
2604
  }
2348
- async addKey(options) {
2349
- await this.client(TABLE).insert({
2350
- id: options.key.kid,
2351
- key: JSON.stringify(options.key),
2352
- expires_at: options.expiresAt.toISOString()
2353
- });
2605
+ // used only for the old backend.auth.keys array
2606
+ addOld(options) {
2607
+ __privateMethod$2(this, _doAdd, doAdd_fn).call(this, options.getString("secret"), "external:backstage-plugin");
2354
2608
  }
2355
- async listKeys() {
2356
- const rows = await this.client(TABLE).select();
2357
- const keys = rows.map((row) => ({
2358
- id: row.id,
2359
- key: JSON.parse(row.key),
2360
- expiresAt: new Date(row.expires_at)
2361
- }));
2362
- const validKeys = [];
2363
- const expiredKeys = [];
2364
- for (const key of keys) {
2365
- if (luxon.DateTime.fromJSDate(key.expiresAt) < luxon.DateTime.local()) {
2366
- expiredKeys.push(key);
2367
- } else {
2368
- validKeys.push(key);
2609
+ async verifyToken(token) {
2610
+ try {
2611
+ const { alg } = jose.decodeProtectedHeader(token);
2612
+ if (alg !== "HS256") {
2613
+ return void 0;
2614
+ }
2615
+ const { sub, aud } = jose.decodeJwt(token);
2616
+ if (sub !== "backstage-server" || aud) {
2617
+ return void 0;
2369
2618
  }
2619
+ } catch (e) {
2620
+ return void 0;
2370
2621
  }
2371
- if (expiredKeys.length > 0) {
2372
- const kids = expiredKeys.map(({ key }) => key.kid);
2373
- this.logger.info(
2374
- `Removing expired plugin service keys, '${kids.join("', '")}'`
2375
- );
2376
- this.client(TABLE).delete().whereIn("id", kids).catch((error) => {
2377
- this.logger.error(
2378
- "Failed to remove expired plugin service keys",
2379
- error
2380
- );
2381
- });
2622
+ for (const entry of __privateGet$3(this, _entries$1)) {
2623
+ try {
2624
+ await jose.jwtVerify(token, entry.key);
2625
+ return { subject: entry.subject };
2626
+ } catch (e) {
2627
+ if (e.code !== "ERR_JWS_SIGNATURE_VERIFICATION_FAILED") {
2628
+ throw e;
2629
+ }
2630
+ }
2382
2631
  }
2383
- return { keys: validKeys };
2632
+ return void 0;
2384
2633
  }
2385
2634
  }
2635
+ _entries$1 = new WeakMap();
2636
+ _doAdd = new WeakSet();
2637
+ doAdd_fn = function(secret, subject) {
2638
+ if (!secret.match(/^\S+$/)) {
2639
+ throw new Error("Illegal secret, must be a valid base64 string");
2640
+ }
2641
+ let key;
2642
+ try {
2643
+ key = jose.base64url.decode(secret);
2644
+ } catch {
2645
+ throw new Error("Illegal secret, must be a valid base64 string");
2646
+ }
2647
+ if (!subject.match(/^\S+$/)) {
2648
+ throw new Error("Illegal subject, must be a set of non-space characters");
2649
+ }
2650
+ __privateGet$3(this, _entries$1).push({ key, subject });
2651
+ };
2386
2652
 
2387
2653
  var __accessCheck$2 = (obj, member, msg) => {
2388
2654
  if (!member.has(obj))
2389
2655
  throw TypeError("Cannot " + msg);
2390
2656
  };
2657
+ var __privateGet$2 = (obj, member, getter) => {
2658
+ __accessCheck$2(obj, member, "read from private field");
2659
+ return member.get(obj);
2660
+ };
2391
2661
  var __privateAdd$2 = (obj, member, value) => {
2392
2662
  if (member.has(obj))
2393
2663
  throw TypeError("Cannot add the same private member more than once");
2394
2664
  member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
2395
2665
  };
2396
- var __privateMethod$2 = (obj, member, method) => {
2397
- __accessCheck$2(obj, member, "access private method");
2398
- return method;
2399
- };
2400
- var _getJwtExpiration, getJwtExpiration_fn;
2401
- function createCredentialsWithServicePrincipal(sub, token) {
2402
- return {
2403
- $$type: "@backstage/BackstageCredentials",
2404
- version: "v1",
2405
- token,
2406
- principal: {
2407
- type: "service",
2408
- subject: sub
2666
+ var _entries;
2667
+ const MIN_TOKEN_LENGTH = 8;
2668
+ class StaticTokenHandler {
2669
+ constructor() {
2670
+ __privateAdd$2(this, _entries, []);
2671
+ }
2672
+ add(options) {
2673
+ const token = options.getString("token");
2674
+ if (!token.match(/^\S+$/)) {
2675
+ throw new Error("Illegal token, must be a set of non-space characters");
2409
2676
  }
2410
- };
2411
- }
2412
- function createCredentialsWithUserPrincipal(sub, token, expiresAt) {
2413
- return {
2414
- $$type: "@backstage/BackstageCredentials",
2415
- version: "v1",
2416
- token,
2417
- expiresAt,
2418
- principal: {
2419
- type: "user",
2420
- userEntityRef: sub
2677
+ if (token.length < MIN_TOKEN_LENGTH) {
2678
+ throw new Error(
2679
+ `Illegal token, must be at least ${MIN_TOKEN_LENGTH} characters length`
2680
+ );
2421
2681
  }
2422
- };
2423
- }
2424
- function createCredentialsWithNonePrincipal() {
2425
- return {
2426
- $$type: "@backstage/BackstageCredentials",
2427
- version: "v1",
2428
- principal: {
2429
- type: "none"
2682
+ const subject = options.getString("subject");
2683
+ if (!subject.match(/^\S+$/)) {
2684
+ throw new Error("Illegal subject, must be a set of non-space characters");
2430
2685
  }
2431
- };
2432
- }
2433
- function toInternalBackstageCredentials(credentials) {
2434
- if (credentials.$$type !== "@backstage/BackstageCredentials") {
2435
- throw new Error("Invalid credential type");
2686
+ __privateGet$2(this, _entries).push({ token, subject });
2436
2687
  }
2437
- const internalCredentials = credentials;
2438
- if (internalCredentials.version !== "v1") {
2439
- throw new Error(
2440
- `Invalid credential version ${internalCredentials.version}`
2441
- );
2688
+ async verifyToken(token) {
2689
+ const entry = __privateGet$2(this, _entries).find((e) => e.token === token);
2690
+ if (!entry) {
2691
+ return void 0;
2692
+ }
2693
+ return { subject: entry.subject };
2442
2694
  }
2443
- return internalCredentials;
2444
2695
  }
2445
- class DefaultAuthService {
2446
- constructor(tokenManager, userTokenHandler, pluginId, disableDefaultAuthPolicy, publicKeyStore, pluginTokenHandler) {
2447
- this.tokenManager = tokenManager;
2448
- this.userTokenHandler = userTokenHandler;
2449
- this.pluginId = pluginId;
2450
- this.disableDefaultAuthPolicy = disableDefaultAuthPolicy;
2451
- this.publicKeyStore = publicKeyStore;
2452
- this.pluginTokenHandler = pluginTokenHandler;
2453
- __privateAdd$2(this, _getJwtExpiration);
2696
+ _entries = new WeakMap();
2697
+
2698
+ const NEW_CONFIG_KEY = "backend.auth.externalAccess";
2699
+ const OLD_CONFIG_KEY = "backend.auth.keys";
2700
+ class ExternalTokenHandler {
2701
+ constructor(handlers) {
2702
+ this.handlers = handlers;
2454
2703
  }
2455
- // allowLimitedAccess is currently ignored, since we currently always use the full user tokens
2456
- async authenticate(token) {
2457
- const pluginResult = await this.pluginTokenHandler.verifyToken(token);
2458
- if (pluginResult) {
2459
- if (pluginResult.limitedUserToken) {
2460
- const userResult2 = await this.userTokenHandler.verifyToken(
2461
- pluginResult.limitedUserToken
2462
- );
2463
- if (!userResult2) {
2464
- throw new errors.AuthenticationError(
2465
- "Invalid user token in plugin token obo claim"
2466
- );
2467
- }
2468
- return createCredentialsWithUserPrincipal(
2469
- userResult2.userEntityRef,
2470
- pluginResult.limitedUserToken,
2471
- __privateMethod$2(this, _getJwtExpiration, getJwtExpiration_fn).call(this, pluginResult.limitedUserToken)
2704
+ static create(options) {
2705
+ var _a, _b;
2706
+ const { config, logger } = options;
2707
+ const staticHandler = new StaticTokenHandler();
2708
+ const legacyHandler = new LegacyTokenHandler();
2709
+ const handlers = {
2710
+ static: staticHandler,
2711
+ legacy: legacyHandler
2712
+ };
2713
+ const handlerConfigs = (_a = config.getOptionalConfigArray(NEW_CONFIG_KEY)) != null ? _a : [];
2714
+ for (const handlerConfig of handlerConfigs) {
2715
+ const type = handlerConfig.getString("type");
2716
+ const handler = handlers[type];
2717
+ if (!handler) {
2718
+ const valid = Object.keys(handlers).map((k) => `'${k}'`).join(", ");
2719
+ throw new Error(
2720
+ `Unknown type '${type}' in ${NEW_CONFIG_KEY}, expected one of ${valid}`
2472
2721
  );
2473
2722
  }
2474
- return createCredentialsWithServicePrincipal(pluginResult.subject);
2723
+ handler.add(handlerConfig.getConfig("options"));
2475
2724
  }
2476
- const userResult = await this.userTokenHandler.verifyToken(token);
2477
- if (userResult) {
2478
- return createCredentialsWithUserPrincipal(
2479
- userResult.userEntityRef,
2480
- token,
2481
- __privateMethod$2(this, _getJwtExpiration, getJwtExpiration_fn).call(this, token)
2725
+ const legacyConfigs = (_b = config.getOptionalConfigArray(OLD_CONFIG_KEY)) != null ? _b : [];
2726
+ if (legacyConfigs.length) {
2727
+ logger.warn(
2728
+ `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
2729
  );
2483
2730
  }
2484
- const { sub, aud } = jose.decodeJwt(token);
2485
- if (sub === "backstage-server" && !aud) {
2486
- await this.tokenManager.authenticate(token);
2487
- return createCredentialsWithServicePrincipal("external:backstage-plugin");
2731
+ for (const handlerConfig of legacyConfigs) {
2732
+ legacyHandler.addOld(handlerConfig);
2488
2733
  }
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;
2498
- }
2499
- return true;
2500
- }
2501
- async getNoneCredentials() {
2502
- return createCredentialsWithNonePrincipal();
2503
- }
2504
- async getOwnServiceCredentials() {
2505
- return createCredentialsWithServicePrincipal(`plugin:${this.pluginId}`);
2734
+ return new ExternalTokenHandler(Object.values(handlers));
2506
2735
  }
2507
- async getPluginRequestToken(options) {
2508
- const { targetPluginId } = options;
2509
- const internalForward = toInternalBackstageCredentials(options.onBehalfOf);
2510
- const { type } = internalForward.principal;
2511
- if (type === "none" && this.disableDefaultAuthPolicy) {
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 };
2736
+ async verifyToken(token) {
2737
+ for (const handler of this.handlers) {
2738
+ const result = await handler.verifyToken(token);
2739
+ if (result) {
2740
+ return result;
2545
2741
  }
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
2742
  }
2559
- return this.userTokenHandler.createLimitedUserToken(backstageToken);
2560
- }
2561
- async listPublicServiceKeys() {
2562
- const { keys } = await this.publicKeyStore.listKeys();
2563
- return { keys: keys.map(({ key }) => key) };
2743
+ return void 0;
2564
2744
  }
2565
2745
  }
2566
- _getJwtExpiration = new WeakSet();
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
- };
2746
+
2574
2747
  const authServiceFactory = backendPluginApi.createServiceFactory({
2575
2748
  service: backendPluginApi.coreServices.auth,
2576
2749
  deps: {
@@ -2585,26 +2758,43 @@ const authServiceFactory = backendPluginApi.createServiceFactory({
2585
2758
  // new auth services in the new backend system.
2586
2759
  tokenManager: backendPluginApi.coreServices.tokenManager
2587
2760
  },
2588
- async factory({ config, discovery, plugin, tokenManager, logger, database }) {
2761
+ async createRootContext({ config, logger }) {
2762
+ const externalTokens = ExternalTokenHandler.create({
2763
+ config,
2764
+ logger
2765
+ });
2766
+ return {
2767
+ externalTokens
2768
+ };
2769
+ },
2770
+ async factory({ config, discovery, plugin, tokenManager, logger, database }, { externalTokens }) {
2589
2771
  const disableDefaultAuthPolicy = Boolean(
2590
2772
  config.getOptionalBoolean(
2591
2773
  "backend.auth.dangerouslyDisableDefaultAuthPolicy"
2592
2774
  )
2593
2775
  );
2594
- const publicKeyStore = await DatabaseKeyStore.create({ database, logger });
2776
+ const publicKeyStore = await DatabaseKeyStore.create({
2777
+ database,
2778
+ logger
2779
+ });
2780
+ const userTokens = UserTokenHandler.create({
2781
+ discovery
2782
+ });
2783
+ const pluginTokens = PluginTokenHandler.create({
2784
+ ownPluginId: plugin.getId(),
2785
+ keyDuration: { hours: 1 },
2786
+ logger,
2787
+ publicKeyStore,
2788
+ discovery
2789
+ });
2595
2790
  return new DefaultAuthService(
2791
+ userTokens,
2792
+ pluginTokens,
2793
+ externalTokens,
2596
2794
  tokenManager,
2597
- new UserTokenHandler({ discovery }),
2598
2795
  plugin.getId(),
2599
2796
  disableDefaultAuthPolicy,
2600
- publicKeyStore,
2601
- PluginTokenHandler.create({
2602
- ownPluginId: plugin.getId(),
2603
- keyDurationSeconds: 60 * 60,
2604
- logger,
2605
- publicKeyStore,
2606
- discovery
2607
- })
2797
+ publicKeyStore
2608
2798
  );
2609
2799
  }
2610
2800
  });
@@ -2760,7 +2950,7 @@ var __accessCheck$1 = (obj, member, msg) => {
2760
2950
  };
2761
2951
  var __privateGet$1 = (obj, member, getter) => {
2762
2952
  __accessCheck$1(obj, member, "read from private field");
2763
- return getter ? getter.call(obj) : member.get(obj);
2953
+ return member.get(obj);
2764
2954
  };
2765
2955
  var __privateAdd$1 = (obj, member, value) => {
2766
2956
  if (member.has(obj))
@@ -2769,7 +2959,7 @@ var __privateAdd$1 = (obj, member, value) => {
2769
2959
  };
2770
2960
  var __privateSet$1 = (obj, member, value, setter) => {
2771
2961
  __accessCheck$1(obj, member, "write to private field");
2772
- setter ? setter.call(obj, value) : member.set(obj, value);
2962
+ member.set(obj, value);
2773
2963
  return value;
2774
2964
  };
2775
2965
  var __privateMethod$1 = (obj, member, method) => {
@@ -2928,13 +3118,11 @@ getLimitedCredentials_fn = async function(req) {
2928
3118
  return (_a = req[limitedCredentialsSymbol]) != null ? _a : req[limitedCredentialsSymbol] = __privateMethod$1(this, _extractLimitedCredentialsFromRequest, extractLimitedCredentialsFromRequest_fn).call(this, req);
2929
3119
  };
2930
3120
  _getCookieOptions = new WeakSet();
2931
- getCookieOptions_fn = async function(req) {
2932
- const originHeader = req.headers.origin;
2933
- const origin = !originHeader || originHeader === "null" ? void 0 : originHeader;
3121
+ getCookieOptions_fn = async function(_req) {
2934
3122
  const externalBaseUrlStr = await __privateGet$1(this, _discovery).getExternalBaseUrl(
2935
3123
  __privateGet$1(this, _pluginId)
2936
3124
  );
2937
- const externalBaseUrl = new URL(origin != null ? origin : externalBaseUrlStr);
3125
+ const externalBaseUrl = new URL(externalBaseUrlStr);
2938
3126
  const secure = externalBaseUrl.protocol === "https:" || externalBaseUrl.hostname === "localhost";
2939
3127
  return {
2940
3128
  domain: externalBaseUrl.hostname,
@@ -3141,8 +3329,8 @@ const httpRouterServiceFactory = backendPluginApi.createServiceFactory(
3141
3329
  httpAuth,
3142
3330
  config
3143
3331
  });
3144
- router.use(createLifecycleMiddleware({ lifecycle }));
3145
3332
  router.use(createAuthIntegrationRouter({ auth }));
3333
+ router.use(createLifecycleMiddleware({ lifecycle }));
3146
3334
  router.use(credentialsBarrier.middleware);
3147
3335
  router.use(createCookieAuthRefreshMiddleware({ auth, httpAuth }));
3148
3336
  return {
@@ -3203,7 +3391,7 @@ var __accessCheck = (obj, member, msg) => {
3203
3391
  };
3204
3392
  var __privateGet = (obj, member, getter) => {
3205
3393
  __accessCheck(obj, member, "read from private field");
3206
- return getter ? getter.call(obj) : member.get(obj);
3394
+ return member.get(obj);
3207
3395
  };
3208
3396
  var __privateAdd = (obj, member, value) => {
3209
3397
  if (member.has(obj))
@@ -3212,7 +3400,7 @@ var __privateAdd = (obj, member, value) => {
3212
3400
  };
3213
3401
  var __privateSet = (obj, member, value, setter) => {
3214
3402
  __accessCheck(obj, member, "write to private field");
3215
- setter ? setter.call(obj, value) : member.set(obj, value);
3403
+ member.set(obj, value);
3216
3404
  return value;
3217
3405
  };
3218
3406
  var __privateMethod = (obj, member, method) => {
@@ -3294,15 +3482,8 @@ findConflictingPath_fn = function(newPath) {
3294
3482
  };
3295
3483
  let DefaultRootHttpRouter = _DefaultRootHttpRouter;
3296
3484
 
3297
- function defaultConfigure(context) {
3298
- const { app, routes, middleware } = context;
3299
- app.use(middleware.helmet());
3300
- app.use(middleware.cors());
3301
- app.use(middleware.compression());
3302
- app.use(middleware.logging());
3303
- app.use(routes);
3304
- app.use(middleware.notFound());
3305
- app.use(middleware.error());
3485
+ function defaultConfigure({ applyDefaults }) {
3486
+ applyDefaults();
3306
3487
  }
3307
3488
  const rootHttpRouterServiceFactory = backendPluginApi.createServiceFactory(
3308
3489
  (options) => ({
@@ -3318,19 +3499,30 @@ const rootHttpRouterServiceFactory = backendPluginApi.createServiceFactory(
3318
3499
  const app = express__default.default();
3319
3500
  const router = DefaultRootHttpRouter.create({ indexPath });
3320
3501
  const middleware = MiddlewareFactory.create({ config, logger });
3502
+ const routes = router.handler();
3503
+ const server = await createHttpServer(
3504
+ app,
3505
+ readHttpServerOptions(config.getOptionalConfig("backend")),
3506
+ { logger }
3507
+ );
3321
3508
  configure({
3322
3509
  app,
3323
- routes: router.handler(),
3510
+ server,
3511
+ routes,
3324
3512
  middleware,
3325
3513
  config,
3326
3514
  logger,
3327
- lifecycle
3515
+ lifecycle,
3516
+ applyDefaults() {
3517
+ app.use(middleware.helmet());
3518
+ app.use(middleware.cors());
3519
+ app.use(middleware.compression());
3520
+ app.use(middleware.logging());
3521
+ app.use(routes);
3522
+ app.use(middleware.notFound());
3523
+ app.use(middleware.error());
3524
+ }
3328
3525
  });
3329
- const server = await createHttpServer(
3330
- app,
3331
- readHttpServerOptions(config.getOptionalConfig("backend")),
3332
- { logger }
3333
- );
3334
3526
  lifecycle.addShutdownHook(() => server.stop());
3335
3527
  await server.start();
3336
3528
  return router;
@@ -3371,7 +3563,7 @@ const schedulerServiceFactory = backendPluginApi.createServiceFactory({
3371
3563
  return backendTasks.TaskScheduler.forPlugin({
3372
3564
  pluginId: plugin.getId(),
3373
3565
  databaseManager,
3374
- logger: backendCommon.loggerToWinstonLogger(logger)
3566
+ logger
3375
3567
  });
3376
3568
  }
3377
3569
  });
@@ -3384,7 +3576,8 @@ const tokenManagerServiceFactory = backendPluginApi.createServiceFactory({
3384
3576
  },
3385
3577
  createRootContext({ config, logger }) {
3386
3578
  return backendCommon.ServerTokenManager.fromConfig(config, {
3387
- logger
3579
+ logger,
3580
+ allowDisabledTokenManager: true
3388
3581
  });
3389
3582
  },
3390
3583
  async factory(_deps, tokenManager) {
@@ -3401,7 +3594,7 @@ const urlReaderServiceFactory = backendPluginApi.createServiceFactory({
3401
3594
  async factory({ config, logger }) {
3402
3595
  return backendCommon.UrlReaders.default({
3403
3596
  config,
3404
- logger: backendCommon.loggerToWinstonLogger(logger)
3597
+ logger
3405
3598
  });
3406
3599
  }
3407
3600
  });