feathers-ucan 0.1.38 → 0.1.40

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.
@@ -1 +1 @@
1
- export declare const VERSION = "0.1.38";
1
+ export declare const VERSION = "0.1.40";
package/lib/index.cjs CHANGED
@@ -94,7 +94,10 @@ class UcanStrategy extends authentication.AuthenticationBaseStrategy {
94
94
  }
95
95
  }
96
96
  verifyConfiguration() {
97
- const allowedKeys = ['entity', 'entityId', 'service', 'header', 'schemes', 'audience'];
97
+ // Allow strategy configuration keys that this package supports. We recently
98
+ // started propagating `core_path` from the app's authentication config, so
99
+ // it must be considered valid here to avoid startup errors.
100
+ const allowedKeys = ['entity', 'entityId', 'service', 'header', 'schemes', 'audience', 'core_path'];
98
101
  for (const key of Object.keys(this.configuration)) {
99
102
  if (!allowedKeys.includes(key)) {
100
103
  throw new Error(`Invalid ucanStrategy option 'authentication.${this.name}.${key}'. Did you mean to set it in 'authentication.jwtOptions'?`);
@@ -173,7 +176,18 @@ class UcanStrategy extends authentication.AuthenticationBaseStrategy {
173
176
  skip_hooks: true,
174
177
  admin_pass: true
175
178
  }));
176
- if (entities.total) return entities.data[0]._id;else throw new NotAuthError$1('Could not find login associated with this ucan');
179
+ // Support both paginated and non-paginated service responses
180
+ // - Paginated: { total, limit, skip, data: [...] }
181
+ // - Non-paginated: Array
182
+ let first = undefined;
183
+ if (entities && typeof entities === 'object' && 'data' in entities) {
184
+ var _entities$data;
185
+ first = (_entities$data = entities.data) == null ? void 0 : _entities$data[0];
186
+ } else if (Array.isArray(entities)) {
187
+ first = entities[0];
188
+ }
189
+ if (first && first._id) return first._id;
190
+ throw new NotAuthError$1('Could not find login associated with this ucan');
177
191
  }
178
192
  }
179
193
  async authenticate(authentication, params) {
@@ -657,6 +671,7 @@ const noThrowAuth = async context => {
657
671
  context = symbolUcan._set(context, [config.core_path, config.entity], entity);
658
672
  }
659
673
  try {
674
+ // Must pass explicit strategy per app requirements
660
675
  context = await authentication.authenticate('jwt')(context).catch(() => {
661
676
  return context;
662
677
  });
@@ -669,6 +684,7 @@ const bareAuth = async context => {
669
684
  const config = context.app.get('authentication');
670
685
  const entity = symbolUcan._get(context, ['auth', config.entity]);
671
686
  if (entity) context = symbolUcan._set(context, [config.core_path, config.entity], entity);
687
+ // Must pass explicit strategy per app requirements
672
688
  return authentication.authenticate('jwt')(context);
673
689
  };
674
690
  const verifyOne = async (ucan, options, log) => {
@@ -766,29 +782,15 @@ const verifyAgainstReqs = (reqs, config, options) => {
766
782
  return async context => {
767
783
  var _v3;
768
784
  const log = options == null ? void 0 : options.log;
769
- // Per latest requirement: UCAN is always at context.params[entityKey].ucan
770
- const authCfg = context.app.get('authentication');
771
- const entityKey = (authCfg == null ? void 0 : authCfg.entity) || 'login';
772
- if (log) {
773
- try {
774
- logUcanParams('verifyAgainstReqs:start', context);
775
- } catch {}
776
- }
777
- const rawUcanPrimary = symbolUcan._get(context.params, [entityKey, 'ucan']);
778
- // Fallback: legacy path if primary missing
779
- const rawUcanFallback = rawUcanPrimary || symbolUcan._get(context.params, config == null ? void 0 : config.client_ucan);
780
- // Normalize the client UCAN the same way the caps path does
781
- // This brings the first check up to speed with the working cap_subjects flow.
782
- let ucan = rawUcanFallback;
783
- if (rawUcanFallback) {
784
- try {
785
- // ucanToken will stringify a UCAN object or return the compact form for strings
786
- const maybe = symbolUcan.ucanToken(rawUcanFallback);
787
- if (maybe && typeof maybe === 'string') ucan = maybe;
788
- if (log && rawUcanFallback !== ucan) console.log('Normalized client UCAN via ucanToken()');
789
- } catch (e) {
790
- if (log) console.log('UCAN normalization skipped (ucanToken threw):', e == null ? void 0 : e.message);
791
- }
785
+ const rawUcan = symbolUcan._get(context.params, config.client_ucan);
786
+ let ucan = rawUcan;
787
+ try {
788
+ // ucanToken will stringify a UCAN object or return the compact form for strings
789
+ const maybe = symbolUcan.ucanToken(rawUcan);
790
+ if (maybe && typeof maybe === 'string') ucan = maybe;
791
+ if (log && rawUcan !== ucan) console.log('Normalized client UCAN via ucanToken()');
792
+ } catch (e) {
793
+ if (log) console.log('UCAN normalization skipped (ucanToken threw):', e == null ? void 0 : e.message);
792
794
  }
793
795
  const audience = (options == null ? void 0 : options.audience) || symbolUcan._get(context.params, config.ucan_aud);
794
796
  if (log) console.log('verify against reqs', reqs);
@@ -1106,7 +1108,7 @@ const ucanAuth = (requiredCapabilities, options) => {
1106
1108
  const loginId = typeof existingLogin === 'string' ? existingLogin : existingLogin == null ? void 0 : existingLogin._id;
1107
1109
  const hasLogin = !!(existingLogin && (typeof existingLogin === 'string' || !!loginId));
1108
1110
  // Per requirement: UCAN is always at context.params[entity].ucan
1109
- const existingUcan = symbolUcan._get(context.params, [entity, 'ucan']);
1111
+ const existingUcan = symbolUcan._get(context.params, configuration.client_ucan || 'client_ucan');
1110
1112
  if (options != null && options.log) console.log('ucan auth', 'hasLogin', hasLogin, 'loginId', loginId, 'existingUcan', !!existingUcan, 'core_path', core_path, 'entity', entity, 'core', context.params[core_path], 'params login', context.params.login, 'required capabilities', requiredCapabilities);
1111
1113
  if (options != null && options.log && !hasLogin) {
1112
1114
  try {