Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
*/
export const METADATA = BindingKey.create(
'authentication.operationMetadata',
);
export const AUTHENTICATION_STRATEGY_EXTENSION_POINT_NAME =
'authentication.strategies';
// Make `CURRENT_USER` the alias of SecurityBindings.USER for backward compatibility
export const CURRENT_USER = SecurityBindings.USER;
}
/**
* The key used to store method-level metadata for `@authenticate`
*/
export const AUTHENTICATION_METADATA_METHOD_KEY = MetadataAccessor.create<
AuthenticationMetadata,
MethodDecorator
>('authentication:method');
/**
* Alias for AUTHENTICATION_METADATA_METHOD_KEY to keep it backward compatible
*/
export const AUTHENTICATION_METADATA_KEY = AUTHENTICATION_METADATA_METHOD_KEY;
/**
* The key used to store class-level metadata for `@authenticate`
*/
export const AUTHENTICATION_METADATA_CLASS_KEY = MetadataAccessor.create<
AuthenticationMetadata,
ClassDecorator
>('authentication:class');
BindingFilter,
BindingSelector,
filterByTag,
isBindingAddress,
} from './binding-filter';
import {BindingAddress} from './binding-key';
import {BindingComparator} from './binding-sorter';
import {BindingCreationPolicy, Context} from './context';
import {ContextView, createViewGetter} from './context-view';
import {ResolutionOptions, ResolutionSession} from './resolution-session';
import {BoundValue, ValueOrPromise} from './value-promise';
const PARAMETERS_KEY = MetadataAccessor.create(
'inject:parameters',
);
const PROPERTIES_KEY = MetadataAccessor.create(
'inject:properties',
);
// A key to cache described argument injections
const METHODS_KEY = MetadataAccessor.create(
'inject:methods',
);
/**
* A function to provide resolution of injected values
*/
export interface ResolverFunction {
(
ctx: Context,
injection: Readonly,
session: ResolutionSession,
} from '@loopback/metadata';
import {Binding, BindingTag} from './binding';
import {
BindingFilter,
BindingSelector,
filterByTag,
isBindingAddress,
} from './binding-filter';
import {BindingAddress} from './binding-key';
import {BindingComparator} from './binding-sorter';
import {BindingCreationPolicy, Context} from './context';
import {ContextView, createViewGetter} from './context-view';
import {ResolutionOptions, ResolutionSession} from './resolution-session';
import {BoundValue, ValueOrPromise} from './value-promise';
const PARAMETERS_KEY = MetadataAccessor.create(
'inject:parameters',
);
const PROPERTIES_KEY = MetadataAccessor.create(
'inject:properties',
);
// A key to cache described argument injections
const METHODS_KEY = MetadataAccessor.create(
'inject:methods',
);
/**
* A function to provide resolution of injected values
*/
export interface ResolverFunction {
(
import {BindingAddress} from './binding-key';
import {BindingComparator} from './binding-sorter';
import {BindingCreationPolicy, Context} from './context';
import {ContextView, createViewGetter} from './context-view';
import {ResolutionOptions, ResolutionSession} from './resolution-session';
import {BoundValue, ValueOrPromise} from './value-promise';
const PARAMETERS_KEY = MetadataAccessor.create(
'inject:parameters',
);
const PROPERTIES_KEY = MetadataAccessor.create(
'inject:properties',
);
// A key to cache described argument injections
const METHODS_KEY = MetadataAccessor.create(
'inject:methods',
);
/**
* A function to provide resolution of injected values
*/
export interface ResolverFunction {
(
ctx: Context,
injection: Readonly,
session: ResolutionSession,
): ValueOrPromise;
}
/**
* An object to provide metadata for `@inject`
for (const i of interceptorsToApply) {
if (appliedInterceptors.has(i)) {
interceptorsToApply.delete(i);
}
}
// Add existing interceptors after ones from the spec
for (const i of appliedInterceptors) {
interceptorsToApply.add(i);
}
return Array.from(interceptorsToApply);
}
/**
* Metadata key for method-level interceptors
*/
export const INTERCEPT_CLASS_KEY = MetadataAccessor.create<
InterceptorOrKey[],
ClassDecorator
>('intercept:class');
/**
* A factory to define `@intercept` for classes. It allows `@intercept` to be
* used multiple times on the same class.
*/
class InterceptClassDecoratorFactory extends ClassDecoratorFactory<
InterceptorOrKey[]
> {
protected mergeWithOwn(ownMetadata: InterceptorOrKey[], target: Object) {
ownMetadata = ownMetadata || [];
return mergeInterceptors(this.spec, ownMetadata);
}
}
loadInterceptors() {
let interceptors =
MetadataInspector.getMethodMetadata(
INTERCEPT_METHOD_KEY,
this.target,
this.methodName,
) ?? [];
const targetClass =
typeof this.target === 'function' ? this.target : this.target.constructor;
const classInterceptors =
MetadataInspector.getClassMetadata(INTERCEPT_CLASS_KEY, targetClass) ??
[];
// Inserting class level interceptors before method level ones
interceptors = mergeInterceptors(classInterceptors, interceptors);
const globalInterceptors = this.getGlobalInterceptorBindingKeys();
// Inserting global interceptors
interceptors = mergeInterceptors(globalInterceptors, interceptors);
debug('Interceptors for %s', this.targetName, interceptors);
return interceptors;
}
}
methodDescriptorOrParameterIndex,
bindingSelector,
metadata: injectionMetadata,
resolve,
},
// Do not deep clone the spec as only metadata is mutable and it's
// shallowly cloned
{cloneInputSpec: false, decoratorName: injectionMetadata.decorator},
);
paramDecorator(target, member!, methodDescriptorOrParameterIndex);
} else if (member) {
// Property or method
if (target instanceof Function) {
throw new Error(
'@inject is not supported for a static property: ' +
DecoratorFactory.getTargetName(target, member),
);
}
if (methodDescriptorOrParameterIndex) {
// Method
throw new Error(
'@inject cannot be used on a method: ' +
DecoratorFactory.getTargetName(
target,
member,
methodDescriptorOrParameterIndex,
),
);
}
const propDecorator: PropertyDecorator = PropertyDecoratorFactory.createDecorator<
Injection
>(
interceptorOrKeys,
{decoratorName: '@intercept'},
)(target, method, methodDescriptor!);
}
if (typeof target === 'function' && !method && !methodDescriptor) {
// Class
return InterceptClassDecoratorFactory.createDecorator(
INTERCEPT_CLASS_KEY,
interceptorOrKeys,
{decoratorName: '@intercept'},
)(target);
}
// Not on a class or method
throw new Error(
'@intercept cannot be used on a property: ' +
DecoratorFactory.getTargetName(target, method, methodDescriptor),
);
};
}
{cloneInputSpec: false, decoratorName: injectionMetadata.decorator},
);
paramDecorator(target, member!, methodDescriptorOrParameterIndex);
} else if (member) {
// Property or method
if (target instanceof Function) {
throw new Error(
'@inject is not supported for a static property: ' +
DecoratorFactory.getTargetName(target, member),
);
}
if (methodDescriptorOrParameterIndex) {
// Method
throw new Error(
'@inject cannot be used on a method: ' +
DecoratorFactory.getTargetName(
target,
member,
methodDescriptorOrParameterIndex,
),
);
}
const propDecorator: PropertyDecorator = PropertyDecoratorFactory.createDecorator<
Injection
>(
PROPERTIES_KEY,
{
target,
member,
methodDescriptorOrParameterIndex,
bindingSelector,
metadata: injectionMetadata,
} else if (Object.prototype.hasOwnProperty.call(target, method)) {
// The method exists in the target, no injections on the super method
// should be honored
options.ownMetadataOnly = true;
}
meta =
MetadataInspector.getAllParameterMetadata>(
PARAMETERS_KEY,
target,
method,
options,
) ?? [];
// Cache the result
cache[method] = meta;
MetadataInspector.defineMetadata[]>>(
METHODS_KEY,
cache,
target,
);
return meta;
}