Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
export function makeAdministrationScopes(
access: string[],
realm: string,
entity: string,
id: string,
actions: string[]
): string[] {
const exhaustive: string[] = [];
const available: string[] = [];
for (const action of actions) {
const scope = `${realm}:${entity}.${id}:${action}`;
exhaustive.push(scope);
if (isSuperset(access, `${realm}:${entity}.:${action}`)) {
available.push(scope);
}
}
const optimizations: string[] = [];
for (const scope of exhaustive) {
const [realm, context, action] = scope.split(":");
const segments = action.split(".");
// Speculatively try grouping actions with trailing `**`
for (let i = 0; i < segments.length - 1; i++) {
const speculation = `${realm}:${context}:${segments
.slice(0, i)
.join(".")}.**`;
if (
}
): Explanation[] {
const explanationsByScope: {
[scope: string]: (Explanation & { degreesOfFreedom: number[] })[];
} = Object.create(null);
for (const template of explanations) {
let templateScope: string = template.scope;
// The score represents the degrees of freedom between the explanation
// template and the matched scope. The lower the score, the more exact the
// match.
const templateSegmentCount = template.scope.split("{").length - 1;
if (templateSegmentCount) {
const injection = inject(template.scope, {
/* eslint-disable @typescript-eslint/camelcase */
current_authorization_id: substitutions.currentAuthorizationId,
current_user_id: substitutions.currentUserId,
current_grant_id: substitutions.currentGrantId,
current_client_id: substitutions.currentClientId
/* eslint-enable @typescript-eslint/camelcase */
});
if (injection === null) {
continue;
}
templateScope = injection;
}
for (const { query, result, parameters } of extract(
const paramsState = url.searchParams.get("state") || null;
const paramsClientId = url.searchParams.get("client_id") || null;
const paramsRedirectUri = url.searchParams.get("redirect_uri") || null;
const paramsScope = url.searchParams.get("scope") || null;
// If we end up creating a new grant, this is the ID we'll use.
const [speculativeGrantId, setSpeculativeGrantId] = useState(() => v4());
// Parse the scopes
const requestedScopeTemplates = paramsScope ? paramsScope.split(" ") : null;
let requestedScopeTemplatesAreValid: boolean | null = null;
if (requestedScopeTemplates) {
try {
// Make sure that the template does not contain variables in addition to
// those that can be used here.
inject(requestedScopeTemplates, {
/* eslint-disable @typescript-eslint/camelcase */
current_client_id: "",
current_grant_id: "",
current_user_id: "",
current_authorization_id: ""
/* eslint-enable @typescript-eslint/camelcase */
});
requestedScopeTemplatesAreValid = true;
} catch (error) {
requestedScopeTemplatesAreValid = false;
}
}
// Get the user, grant, and client from the API.
const { loading, cacheValue } = useGraphQL<
}
// We have an error to redirect
if (url.searchParams.has("error")) {
setRedirecting(true);
setSpeculativeGrantId(v4());
window.location.replace(url.href);
return;
}
// Check that all requested scopes are already granted
const grantedScopes = grant && grant.scopes;
if (
grantedScopes &&
requestedScopeTemplates &&
isSuperset(grantedScopes, requestedScopeTemplates)
) {
// TODO: We need to allow the app to force us to show a confirmation
// screen. IIRC this is part of the OpenID Connect spec, but I have
// useless airplane wifi right now. This should be an easy thing to
// implement here, so we can enable automatic redirection.
//
// Found the spec: https://openid.net/specs/openid-connect-core-1_0.html#rfc.section.3.1.2.1
//
// onGrantAccess();
}
}
}, [
paramsClientId,
if (!credential) {
throw new AuthenticationError("No such credential exists.");
}
const values = {
currentAuthorizationId: authorizationId,
currentUserId: credential.userId,
currentGrantId: null,
currentClientId: null
};
// Make sure the user can create new authorizations.
const user = await User.read(tx, credential.userId);
if (
!isSuperset(
await user.access(tx, values),
createV2AuthXScope(
realm,
{
type: "authorization",
authorizationId: "",
grantId: "",
clientId: "",
userId: user.id
},
{
basic: "*",
scopes: "*",
secrets: "*"
}
)
// If we have a value for the variable, use it.
const value = values[segment.slice(1, segment.length - 1)];
if (typeof value === "string") {
segments.push(value);
}
// If no value could be found, omit the entire template.
continue template;
}
domains.push(segments.join("."));
}
scopes.push(domains.join(":"));
}
return safeSimplify(scopes);
}
// If behavior is `undefined`, then the custom function will handle responding
// to the request.
if (!behavior) {
meta.message = "Request handled by custom behavior function.";
meta.rule = rule;
return;
}
// Nothing else to do; proxy the request.
if (!behavior.sendTokenToTargetWithScopes) {
forward(behavior.proxyOptions, rule, behavior);
return;
}
const scopes = behavior.sendTokenToTargetWithScopes
? simplify(behavior.sendTokenToTargetWithScopes)
: [];
const hash = hashScopes(scopes);
try {
const token = cookies.get(`authx.t.${hash}`);
const payload = token && decode(token);
if (
payload &&
typeof payload === "object" &&
typeof payload.exp === "number" &&
payload.exp >
Date.now() / 1000 + (this._config.tokenMinimumRemainingLife || 30)
) {
// We already have a valid token.
request.headers.authorization = `Bearer ${token}`;
// Validate `userId`.
if (!validateIdFormat(input.userId)) {
throw new ValidationError("The provided `userId` is an invalid ID.");
}
// Validate `administration`.
for (const { roleId, scopes } of input.administration) {
if (!validateIdFormat(roleId)) {
throw new ValidationError(
"The provided `administration` list contains a `roleId` that is an invalid ID."
);
}
for (const scope of scopes) {
if (!isValidScopeLiteral(scope)) {
throw new ValidationError(
"The provided `administration` list contains a `scopes` list with an invalid scope."
);
}
}
}
const tx = await pool.connect();
try {
const values = {
currentAuthorizationId: a.id,
currentUserId: a.userId,
currentGrantId: a.grantId,
currentClientId: (await a.grant(tx))?.clientId ?? null
};
return args.authorities.map(async input => {
// Validate `id`.
if (typeof input.id === "string" && !validateIdFormat(input.id)) {
throw new ValidationError("The provided `id` is an invalid ID.");
}
// Validate `administration`.
for (const { roleId, scopes } of input.administration) {
if (!validateIdFormat(roleId)) {
throw new ValidationError(
"The provided `administration` list contains a `roleId` that is an invalid ID."
);
}
for (const scope of scopes) {
if (!isValidScopeLiteral(scope)) {
throw new ValidationError(
"The provided `administration` list contains a `scopes` list with an invalid scope."
);
}
}
}
const tx = await pool.connect();
try {
const values = {
currentAuthorizationId: a.id,
currentUserId: a.userId,
currentGrantId: a.grantId,
currentClientId: (await a.grant(tx))?.clientId ?? null
};
return args.authorities.map(async input => {
// Validate `id`.
if (typeof input.id === "string" && !validateIdFormat(input.id)) {
throw new ValidationError("The provided `id` is an invalid ID.");
}
// Validate `administration`.
for (const { roleId, scopes } of input.administration) {
if (!validateIdFormat(roleId)) {
throw new ValidationError(
"The provided `administration` list contains a `roleId` that is an invalid ID."
);
}
for (const scope of scopes) {
if (!isValidScopeLiteral(scope)) {
throw new ValidationError(
"The provided `administration` list contains a `scopes` list with an invalid scope."
);
}
}
}
const tx = await pool.connect();
try {
const values = {
currentAuthorizationId: a.id,
currentUserId: a.userId,
currentGrantId: a.grantId,
currentClientId: (await a.grant(tx))?.clientId ?? null
};