Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Authentication failed on aggregation with subdocuments #92

Open
philippewinter opened this issue Aug 19, 2020 · 3 comments
Open

Authentication failed on aggregation with subdocuments #92

philippewinter opened this issue Aug 19, 2020 · 3 comments

Comments

@philippewinter
Copy link

Hi,

I'm trying to use aggregate on initial access to a document, I have encrypted the subdocument. Error: UnhandledPromiseRejectionWarning: Error: Authentication failed: Only some authenticated fields were selected by the query. Either all or none of the authenticated fields (quotes,_ct,_ac) should be selected for proper authentication.

My Code:

const companySchema = new mongoose.Schema({
    name: String,
    street: String,
    city: String,
    state: String,
    country: String,
    zip: String,
    base: String,
    taxID: String,
    phone: String,
    logo: String,
    csvImport: [{
        effDate: Date,
        prices: [{
            effDate: Date,
            expDate: Date,
            icao: String,
            obs: String,
            galFrom: Number,
            galTo: Number,
            price: Number,
        }]
    }],
    acfts: [acftSchema],
    uplifts: [upliftSchema],
    autoRelease: {
        type: Boolean,
        default: false
    },
    quotes: [quoteSchema],
    users: [userSchema],
    providers: [{
        type: mongoose.Schema.Types.ObjectId,
        ref: "fuelProvider"
    }],
    cards: [cardSchema],
    customerNumber: [customerNumberSchema],
    settings: [companySettingsSchema],
    active: {
        type: Boolean,
        default: true
    },
    stripe: {
        id: String,
        email: String
    },
    disabledProviders: [mongoose.Schema.Types.ObjectId]
}, { timestamps: { createdAt: 'created_at' } });

companySchema.plugin(encrypt, {
    secret: process.env.encKey,
    additionalAuthenticatedFields: ['quotes'],
    encryptedFields: []
});

--------------------------------

var QuoteSchema = new mongoose.Schema({
    registrationMark: {
        type: String,
        uppercase: true
    },
    flightDate: Date,
    origin: {
        type: String,
        uppercase: true
    },
    arrivalDate: Date,
    destination: {
        type: String,
        uppercase: true
    },
    fbo: String,
    fuelQuantity: String,
    bids: [bidSchema],
    crew: [userSchema],
    sent: {
        type: Number,
        default: 1
    },
    nextLeg: mongoose.Schema.Types.ObjectId,
    tanker: {
        type: Boolean,
        default: false
    }
}, { timestamps: { createdAt: 'created_at' } });


QuoteSchema.plugin(encrypt, {
    secret: process.env.encKey,
    encryptedFields: ['fuelQuantity'],
});

--------------------------------

let company = await Company.aggregate([{ $match: { _id: req.user.parent()._id } }, { $sort: { 'quote.flightDate': 1 } }, {
			$project: {
				quotes: {
					$filter: {
						input: "$quotes",
						as: "quote",
						cond: { $and: [{ $gt: ["$$quote.flightDate", new Date(moment().startOf('day'))] }, { $lt: ["$$quote.flightDate", new Date(moment().add(30, 'days'))] }, { $in: ['$$quote.registrationMark', acftTail] }] }
					}
				}
			}
		}]);

@karenpommeroy
Copy link

karenpommeroy commented Feb 2, 2021

Same here

import { Document, model, Schema } from "mongoose";
import encrypt from "mongoose-encryption";
import mongooseHidden from "mongoose-hidden";
`
export interface ISettings {
    userId: string;
    mapbox: {
        user: string;
        publicToken: string;
        privateToken: string;
    };
}

export type SettingsModel = ISettings & Document;

export const SettingsSchema = new Schema(
    {
        userId: { type: Schema.Types.ObjectId, ref: "User", required: true },
        mapbox: {
            user: String,
            publicToken: String,
            privateToken: String,
        },
    },
    {
        timestamps: true,
    },
);

SettingsSchema.set("toJSON", {
    virtuals: true,
});

SettingsSchema.plugin(encrypt, {
    secret: "dupa",
    encryptedFields: ["mapbox.privateToken"],
});

SettingsSchema.plugin(mongooseHidden({ hidden: { __t: true } }));

export const Settings = model<SettingsModel>("Settings", SettingsSchema);

Then simple mongoose.find gives me "Authentication failed".

I trakced that function authenticateSync gives me error because

var authentic = bufferEqual(basicAC, expectedHMAC);     // Here bufferEqual returns false
if (!authentic){
    throw new Error('Authentication failed');
}

@joegoldbeck joegoldbeck changed the title Authentication failed Authentication failed on aggregations Apr 28, 2021
@joegoldbeck
Copy link
Owner

@karenpommeroy I wonder if this is related to the mongooseHidden plugin you added. If you remove that, or perhaps simply reverse the order in which you add the plugins, does that solve the issue?

@joegoldbeck joegoldbeck changed the title Authentication failed on aggregations Authentication failed on aggregations with subdocuments Apr 28, 2021
@joegoldbeck joegoldbeck changed the title Authentication failed on aggregations with subdocuments Authentication failed on aggregations Apr 28, 2021
@joegoldbeck joegoldbeck changed the title Authentication failed on aggregations Authentication failed on aggregation with subdocuments Apr 28, 2021
@joegoldbeck
Copy link
Owner

For the original issue cited, aggregations in general aren't a tested aspect of this package. In general, I'd expect they might work if the fields involved aren't encrypted. However, in this particular case, the entire quotes subdocument is marked to be authenticated, but then only some of its fields are returned in the aggregation, which means authentication cannot be performed. Hence, the error returned!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants