@aws-amplify/datastore
Version:
AppSyncLocal support for aws-amplify
132 lines (130 loc) • 5.22 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.multiAuthStrategy = void 0;
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
const core_1 = require("@aws-amplify/core");
const types_1 = require("../types");
function getProviderFromRule(rule) {
// private with no provider means userPools
if (rule.allow === 'private' && !rule.provider) {
return types_1.ModelAttributeAuthProvider.USER_POOLS;
}
// public with no provider means apiKey
if (rule.allow === 'public' && !rule.provider) {
return types_1.ModelAttributeAuthProvider.API_KEY;
}
return rule.provider;
}
function sortAuthRulesWithPriority(rules) {
const allowSortPriority = [
types_1.ModelAttributeAuthAllow.CUSTOM,
types_1.ModelAttributeAuthAllow.OWNER,
types_1.ModelAttributeAuthAllow.GROUPS,
types_1.ModelAttributeAuthAllow.PRIVATE,
types_1.ModelAttributeAuthAllow.PUBLIC,
];
const providerSortPriority = [
types_1.ModelAttributeAuthProvider.FUNCTION,
types_1.ModelAttributeAuthProvider.USER_POOLS,
types_1.ModelAttributeAuthProvider.OIDC,
types_1.ModelAttributeAuthProvider.IAM,
types_1.ModelAttributeAuthProvider.API_KEY,
];
return [...rules].sort((a, b) => {
if (a.allow === b.allow) {
return (providerSortPriority.indexOf(getProviderFromRule(a)) -
providerSortPriority.indexOf(getProviderFromRule(b)));
}
return (allowSortPriority.indexOf(a.allow) - allowSortPriority.indexOf(b.allow));
});
}
function getAuthRules({ rules, currentUser, }) {
// Using Set to ensure uniqueness
const authModes = new Set();
rules.forEach(rule => {
switch (rule.allow) {
case types_1.ModelAttributeAuthAllow.CUSTOM:
// custom with no provider -> function
if (!rule.provider ||
rule.provider === types_1.ModelAttributeAuthProvider.FUNCTION) {
authModes.add('lambda');
}
break;
case types_1.ModelAttributeAuthAllow.GROUPS:
case types_1.ModelAttributeAuthAllow.OWNER: {
// We shouldn't attempt User Pool or OIDC if there isn't an authenticated user
if (currentUser) {
if (rule.provider === types_1.ModelAttributeAuthProvider.USER_POOLS) {
authModes.add('userPool');
}
else if (rule.provider === types_1.ModelAttributeAuthProvider.OIDC) {
authModes.add('oidc');
}
}
break;
}
case types_1.ModelAttributeAuthAllow.PRIVATE: {
// We shouldn't attempt private if there isn't an authenticated user
if (currentUser) {
// private with no provider means userPools
if (!rule.provider ||
rule.provider === types_1.ModelAttributeAuthProvider.USER_POOLS) {
authModes.add('userPool');
}
else if (rule.provider === types_1.ModelAttributeAuthProvider.IAM) {
authModes.add('iam');
}
}
break;
}
case types_1.ModelAttributeAuthAllow.PUBLIC: {
if (rule.provider === types_1.ModelAttributeAuthProvider.IAM) {
authModes.add('iam');
}
else if (!rule.provider ||
rule.provider === types_1.ModelAttributeAuthProvider.API_KEY) {
// public with no provider means apiKey
authModes.add('apiKey');
}
break;
}
}
});
return Array.from(authModes);
}
/**
* Returns an array of auth modes to try based on the schema, model, and
* authenticated user (or lack thereof). Rules are sourced from `getAuthRules`
* and returned in the order they ought to be attempted.
*
* @see sortAuthRulesWithPriority
* @see getAuthRules
*
* @param param0 The `{schema, modelName}` to inspect.
* @returns A sorted array of auth modes to attempt.
*/
const multiAuthStrategy = () => async ({ schema, modelName }) => {
let currentUser;
try {
const authSession = await (0, core_1.fetchAuthSession)();
if (authSession.tokens.accessToken) {
// the user is authenticated
currentUser = authSession;
}
}
catch (e) {
// No current user
}
const { attributes } = schema.namespaces.user.models[modelName];
if (attributes) {
const authAttribute = attributes.find(attr => attr.type === 'auth');
if (authAttribute?.properties?.rules) {
const sortedRules = sortAuthRulesWithPriority(authAttribute.properties.rules);
return getAuthRules({ currentUser, rules: sortedRules });
}
}
return [];
};
exports.multiAuthStrategy = multiAuthStrategy;
//# sourceMappingURL=multiAuthStrategy.js.map