// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 import { ResourcesConfig } from '../bridge-types'; type GraphQLConfig = Exclude['GraphQL']; type ModelIntrospectionSchema = Exclude< Exclude['modelIntrospection'], undefined >; type Model = ModelIntrospectionSchema['models'][string]; interface AuthAttribute { type: 'auth'; properties: { rules: AuthRule[]; }; } /** * Only the portions of an Auth rule we care about. */ type AuthRule = | { allow: 'owner'; ownerField?: string; } | { allow: 'groups'; groupsField: string; }; /** * Given an introspection schema model, returns all owner fields. * * @param model Model from an introspection schema * @returns List of owner field names */ export function resolveOwnerFields(model: Model): string[] { const ownerFields = new Set(); for (const attr of model.attributes || []) { if (isAuthAttribute(attr)) { for (const rule of attr.properties.rules) { if (rule.allow === 'owner') { ownerFields.add(rule.ownerField || 'owner'); } else if (rule.allow === 'groups' && rule.groupsField !== undefined) { // only valid for dynamic group(s) // static group auth will have an array of predefined groups in the attribute, groups: string[] // but `groupsField` will be undefined ownerFields.add(rule.groupsField); } } } } return Array.from(ownerFields); } /** * Type guard that identifies an auth attribute with an attached rules list that * specifies an `allow` attribute at a minimum. * * @param attribute Any object. Ideally a model introspection schema model attribute * @returns True if given object is an auth attribute */ function isAuthAttribute(attribute: any): attribute is AuthAttribute { if (attribute?.type === 'auth') { if (typeof attribute?.properties === 'object') { if (Array.isArray(attribute?.properties?.rules)) { return (attribute?.properties?.rules as any[]).every( (rule) => !!rule.allow, ); } } } return false; }