@aws-amplify/amplify-category-auth
Version:
amplify-cli authentication plugin
340 lines • 17 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAdminAuthFunction = exports.updateUserPoolGroups = exports.createUserPoolGroups = exports.removeDeprecatedProps = exports.saveResourceParameters = exports.copyCfnTemplate = exports.getResourceUpdater = exports.getResourceSynthesizer = void 0;
const amplify_cli_core_1 = require("@aws-amplify/amplify-cli-core");
const amplify_prompts_1 = require("@aws-amplify/amplify-prompts");
const fs_extra_1 = require("fs-extra");
const lodash_1 = require("lodash");
const path = __importStar(require("path"));
const uuid_1 = require("uuid");
const constants_1 = require("../constants");
const generate_user_pool_group_stack_template_1 = require("./generate-user-pool-group-stack-template");
const getResourceSynthesizer = async (context, request) => {
await lambdaTriggers(request, context, null);
await addAdminAuth(context, request.resourceName, 'add', request.adminQueryGroup);
await copyS3Assets(request);
return request;
};
exports.getResourceSynthesizer = getResourceSynthesizer;
const getResourceUpdater = async (context, request) => {
var _a;
const resources = context.amplify.getProjectMeta();
const adminQueriesFunctionName = (0, lodash_1.get)(resources, ['api', 'AdminQueries', 'dependsOn'], [])
.filter((resource) => resource.category === amplify_cli_core_1.AmplifyCategories.FUNCTION)
.map((resource) => resource.resourceName)
.find((resourceName) => resourceName.includes('AdminQueries'));
if (adminQueriesFunctionName) {
await addAdminAuth(context, request.resourceName, 'update', request.adminQueryGroup, adminQueriesFunctionName);
}
else {
await addAdminAuth(context, request.resourceName, 'add', request.adminQueryGroup);
}
const providerPlugin = context.amplify.getPluginInstance(context, 'awscloudformation');
const previouslySaved = JSON.parse(((_a = providerPlugin.loadResourceParameters(context, 'auth', request.resourceName)) === null || _a === void 0 ? void 0 : _a.triggers) || '{}');
await lambdaTriggers(request, context, previouslySaved);
await copyS3Assets(request);
return request;
};
exports.getResourceUpdater = getResourceUpdater;
const copyCfnTemplate = async (context, category, options, cfnFilename) => {
const targetDir = path.join(amplify_cli_core_1.pathManager.getBackendDirPath(), category, options.resourceName);
const copyJobs = [
{
dir: constants_1.cfnTemplateRoot,
template: cfnFilename,
target: path.join(targetDir, `${options.resourceName}-cloudformation-template.yml`),
paramsFile: path.join(targetDir, 'parameters.json'),
},
];
const privateParams = { ...options };
constants_1.privateKeys.forEach((p) => delete privateParams[p]);
return context.amplify.copyBatch(context, copyJobs, privateParams, true);
};
exports.copyCfnTemplate = copyCfnTemplate;
const saveResourceParameters = (context, providerName, category, resource, params, envSpecificParams = []) => {
const provider = context.amplify.getPluginInstance(context, providerName);
let privateParams = { ...params };
constants_1.privateKeys.forEach((p) => delete privateParams[p]);
privateParams = (0, exports.removeDeprecatedProps)(privateParams);
provider.saveResourceParameters(context, category, resource, privateParams, envSpecificParams);
};
exports.saveResourceParameters = saveResourceParameters;
const removeDeprecatedProps = (props) => {
[
'authRoleName',
'unauthRoleName',
'userpoolClientName',
'roleName',
'policyName',
'mfaLambdaLogPolicy',
'mfaPassRolePolicy',
'mfaLambdaIAMPolicy',
'userpoolClientLogPolicy',
'userpoolClientLambdaPolicy',
'lambdaLogPolicy',
'openIdRolePolicy',
'openIdLambdaIAMPolicy',
'mfaLambdaRole',
'openIdLambdaRoleName',
'CreateAuthChallenge',
'CustomMessage',
'DefineAuthChallenge',
'PostAuthentication',
'PostConfirmation',
'PreAuthentication',
'PreSignup',
'VerifyAuthChallengeResponse',
].forEach((deprecatedField) => delete props[deprecatedField]);
return props;
};
exports.removeDeprecatedProps = removeDeprecatedProps;
const lambdaTriggers = async (coreAnswers, context, previouslySaved) => {
const { handleTriggers } = await Promise.resolve().then(() => __importStar(require('./trigger-flow-auth-helper')));
let triggerKeyValues = {};
let authTriggerConnections;
if (coreAnswers.triggers) {
const triggerConfig = (await handleTriggers(context, coreAnswers, previouslySaved));
triggerKeyValues = triggerConfig.triggers;
authTriggerConnections = triggerConfig.authTriggerConnections;
coreAnswers.triggers = triggerKeyValues ? amplify_cli_core_1.JSONUtilities.stringify(triggerKeyValues) : '{}';
if (amplify_cli_core_1.FeatureFlags.getBoolean('auth.breakCircularDependency')) {
if (Array.isArray(authTriggerConnections) && authTriggerConnections.length > 0) {
coreAnswers.authTriggerConnections = amplify_cli_core_1.JSONUtilities.stringify(authTriggerConnections);
}
else {
delete coreAnswers.authTriggerConnections;
}
}
coreAnswers.breakCircularDependency = amplify_cli_core_1.FeatureFlags.getBoolean('auth.breakCircularDependency');
if (triggerKeyValues) {
coreAnswers.parentStack = { Ref: 'AWS::StackId' };
}
coreAnswers.permissions = await context.amplify.getTriggerPermissions(context, coreAnswers.triggers, amplify_cli_core_1.AmplifyCategories.AUTH, coreAnswers.resourceName);
}
else if (previouslySaved) {
const targetDir = amplify_cli_core_1.pathManager.getBackendDirPath();
Object.keys(previouslySaved).forEach((p) => {
delete coreAnswers[p];
});
await context.amplify.deleteAllTriggers(previouslySaved, coreAnswers.resourceName, targetDir, context);
}
if (coreAnswers.triggers && coreAnswers.triggers === '[]') {
delete coreAnswers.triggers;
}
const dependsOnKeys = Object.keys(triggerKeyValues).map((i) => `${coreAnswers.resourceName}${i}`);
coreAnswers.dependsOn = context.amplify.dependsOnBlock(context, dependsOnKeys, 'Cognito');
};
const createUserPoolGroups = async (context, resourceName, userPoolGroupList) => {
if (userPoolGroupList && userPoolGroupList.length > 0) {
const userPoolGroupPrecedenceList = [];
for (let i = 0; i < userPoolGroupList.length; ++i) {
userPoolGroupPrecedenceList.push({
groupName: userPoolGroupList[i],
precedence: i + 1,
});
}
const userPoolGroupFile = path.join(amplify_cli_core_1.pathManager.getBackendDirPath(), amplify_cli_core_1.AmplifyCategories.AUTH, 'userPoolGroups', 'user-pool-group-precedence.json');
const userPoolGroupParams = path.join(amplify_cli_core_1.pathManager.getBackendDirPath(), amplify_cli_core_1.AmplifyCategories.AUTH, 'userPoolGroups', 'build', 'parameters.json');
const groupParams = {
AuthRoleArn: {
'Fn::GetAtt': ['AuthRole', 'Arn'],
},
UnauthRoleArn: {
'Fn::GetAtt': ['UnauthRole', 'Arn'],
},
};
amplify_cli_core_1.JSONUtilities.writeJson(userPoolGroupParams, groupParams);
amplify_cli_core_1.JSONUtilities.writeJson(userPoolGroupFile, userPoolGroupPrecedenceList);
context.amplify.updateamplifyMetaAfterResourceAdd(amplify_cli_core_1.AmplifyCategories.AUTH, 'userPoolGroups', {
service: 'Cognito-UserPool-Groups',
providerPlugin: 'awscloudformation',
dependsOn: [
{
category: amplify_cli_core_1.AmplifyCategories.AUTH,
resourceName,
attributes: ['UserPoolId', 'AppClientIDWeb', 'AppClientID', 'IdentityPoolId'],
},
],
});
await (0, generate_user_pool_group_stack_template_1.generateUserPoolGroupStackTemplate)(context, resourceName);
}
};
exports.createUserPoolGroups = createUserPoolGroups;
const updateUserPoolGroups = async (context, resourceName, userPoolGroupList) => {
var _a, _b;
if (userPoolGroupList && userPoolGroupList.length > 0) {
const userPoolGroupFolder = path.join(amplify_cli_core_1.pathManager.getBackendDirPath(), amplify_cli_core_1.AmplifyCategories.AUTH, 'userPoolGroups');
const prevUserPoolGroupPrecedenceList = (_a = amplify_cli_core_1.JSONUtilities.readJson(path.join(userPoolGroupFolder, 'user-pool-group-precedence.json'), {
throwIfNotExist: false,
})) !== null && _a !== void 0 ? _a : [];
const currentUserPoolGroupPrecedenceList = userPoolGroupList.map((groupName, index) => ({
groupName,
precedence: index + 1,
}));
const updatedUserPoolGroupList = [];
currentUserPoolGroupPrecedenceList.forEach((group1) => {
let newGroup = group1;
prevUserPoolGroupPrecedenceList.forEach((group2) => {
const oldGroup = group2;
if (newGroup.groupName === oldGroup.groupName) {
newGroup = { ...oldGroup, ...newGroup };
}
});
updatedUserPoolGroupList.push(newGroup);
});
(0, fs_extra_1.ensureDirSync)(userPoolGroupFolder);
amplify_cli_core_1.JSONUtilities.writeJson(path.join(userPoolGroupFolder, 'user-pool-group-precedence.json'), updatedUserPoolGroupList);
context.amplify.updateamplifyMetaAfterResourceUpdate(amplify_cli_core_1.AmplifyCategories.AUTH, 'userPoolGroups', 'service', 'Cognito-UserPool-Groups');
context.amplify.updateamplifyMetaAfterResourceUpdate(amplify_cli_core_1.AmplifyCategories.AUTH, 'userPoolGroups', 'providerPlugin', 'awscloudformation');
const authInputs = amplify_cli_core_1.stateManager.getResourceInputsJson(undefined, amplify_cli_core_1.AmplifyCategories.AUTH, resourceName);
const attributes = ['UserPoolId', 'AppClientIDWeb', 'AppClientID'];
if ((_b = authInputs === null || authInputs === void 0 ? void 0 : authInputs.cognitoConfig) === null || _b === void 0 ? void 0 : _b.identityPoolName) {
attributes.push('IdentityPoolId');
}
context.amplify.updateamplifyMetaAfterResourceUpdate(amplify_cli_core_1.AmplifyCategories.AUTH, 'userPoolGroups', 'dependsOn', [
{
category: amplify_cli_core_1.AmplifyCategories.AUTH,
resourceName,
attributes,
},
]);
await (0, generate_user_pool_group_stack_template_1.generateUserPoolGroupStackTemplate)(context, resourceName);
}
};
exports.updateUserPoolGroups = updateUserPoolGroups;
const addAdminAuth = async (context, authResourceName, operation, adminGroup, functionName) => {
if (adminGroup) {
if (!functionName) {
const [shortId] = (0, uuid_1.v4)().split('-');
functionName = `AdminQueries${shortId}`;
}
await (0, exports.createAdminAuthFunction)(context, authResourceName, functionName, adminGroup, operation);
await createAdminAuthAPI(context, authResourceName, functionName, operation);
}
};
const createAdminAuthFunction = async (context, authResourceName, functionName, adminGroup, operation) => {
const targetDir = path.join(amplify_cli_core_1.pathManager.getBackendDirPath(), amplify_cli_core_1.AmplifyCategories.FUNCTION, functionName);
let lambdaGroupVar = adminGroup;
const dependsOn = [];
dependsOn.push({
category: amplify_cli_core_1.AmplifyCategories.AUTH,
resourceName: authResourceName,
attributes: ['UserPoolId'],
});
if (!lambdaGroupVar) {
lambdaGroupVar = 'NONE';
}
if (operation === 'add') {
const functionProps = {
functionName: `${functionName}`,
roleName: `${functionName}LambdaRole`,
dependsOn,
authResourceName,
lambdaGroupVar,
};
const copyJobs = [
{
dir: constants_1.adminAuthAssetRoot,
template: 'admin-auth-app.js',
target: path.join(targetDir, 'src/app.js'),
},
{
dir: constants_1.adminAuthAssetRoot,
template: 'admin-auth-cognitoActions.js',
target: path.join(targetDir, 'src/cognitoActions.js'),
},
{
dir: constants_1.adminAuthAssetRoot,
template: 'admin-auth-index.js',
target: path.join(targetDir, 'src/index.js'),
},
{
dir: constants_1.adminAuthAssetRoot,
template: 'admin-auth-package.json',
target: path.join(targetDir, 'src/package.json'),
},
{
dir: constants_1.adminAuthAssetRoot,
template: 'admin-queries-function-template.json.ejs',
target: path.join(targetDir, `${functionName}-cloudformation-template.json`),
},
];
await context.amplify.copyBatch(context, copyJobs, functionProps, true);
const backendConfigs = {
service: amplify_cli_core_1.AmplifySupportedService.LAMBDA,
providerPlugin: 'awscloudformation',
build: true,
dependsOn,
};
await context.amplify.updateamplifyMetaAfterResourceAdd(amplify_cli_core_1.AmplifyCategories.FUNCTION, functionName, backendConfigs);
amplify_prompts_1.printer.success(`Successfully added ${functionName} function locally`);
}
else {
amplify_prompts_1.printer.success(`Successfully updated ${functionName} function locally`);
}
};
exports.createAdminAuthFunction = createAdminAuthFunction;
const createAdminAuthAPI = async (context, authResourceName, functionName, operation) => {
const apiName = 'AdminQueries';
const dependsOn = [
{
category: amplify_cli_core_1.AmplifyCategories.AUTH,
resourceName: authResourceName,
attributes: ['UserPoolId'],
},
{
category: amplify_cli_core_1.AmplifyCategories.FUNCTION,
resourceName: functionName,
attributes: ['Arn', 'Name'],
},
];
const apiProps = {
apiName,
functionName,
authResourceName,
dependsOn,
};
if (operation === 'add') {
await context.amplify.invokePluginMethod(context, amplify_cli_core_1.AmplifyCategories.API, undefined, 'addAdminQueriesApi', [context, apiProps]);
amplify_prompts_1.printer.success(`Successfully added ${apiName} API locally`);
}
else {
await context.amplify.invokePluginMethod(context, amplify_cli_core_1.AmplifyCategories.API, undefined, 'updateAdminQueriesApi', [context, apiProps]);
amplify_prompts_1.printer.success(`Successfully updated ${apiName} API locally`);
}
};
const copyS3Assets = async (request) => {
const targetDir = path.join(amplify_cli_core_1.pathManager.getBackendDirPath(), amplify_cli_core_1.AmplifyCategories.AUTH, request.resourceName, 'assets');
const triggers = request.triggers ? amplify_cli_core_1.JSONUtilities.parse(request.triggers) : null;
const confirmationFileNeeded = request.triggers && triggers.CustomMessage && triggers.CustomMessage.includes('verification-link');
if (confirmationFileNeeded) {
if (!(0, fs_extra_1.existsSync)(targetDir)) {
const source = path.join(constants_1.triggerRoot, 'CustomMessage/assets');
(0, fs_extra_1.copySync)(source, targetDir);
}
}
};
//# sourceMappingURL=synthesize-resources.js.map