Keystone-classic: Provide hostname etc from request to schemaplugins and hooks

Created on 21 Jul 2016  Â·  8Comments  Â·  Source: keystonejs/keystone-classic

I need to write a mongoose plugin. where I need a Request object to find hostname.

module.exports = exports = function(schema, options) {
    schema.add({
        hostname: String
    })

    schema.pre('save', true, function(next, done) {
        this.hostname = req.headers.host; //need request object
        next();
        setTimeout(done, 100);
    });
}

I have raised related question in stackoverflow

help wanted needs input

All 8 comments

This is not currently possible. The only thing that is passed to the schema plugins is the user: https://github.com/keystonejs/keystone/blob/0e5a4a11d13d4ced058b392b119140f42116dc7e/lib/updateHandler.js#L177

To have the hostname, it would similarly need to be passed. However, that is extra work for every call, without many things using it.

I wonder if there could instead be some session context object that could be used instead? This would be a breaking API change, but it would allow pluggable additions, and the object would be created once per session and just referenced on each save.

so instead of

function UpdateHandler (list, item, req, res, options) {
        …
    this.user = req.user;
        …
}
…
    var saveItem = function () {

        // Make current user available to pre/post save events
        this.item._req_user = this.user;

we'd have

function UpdateHandler (list, item, req, res, options) {
        …
    this.context = req.session.context;
        …
}
…
    var saveItem = function () {

        // Make current user etc available to pre/post save events
        this.item.__context = this.context;

You could then add the hostname to the context object in one of the other hooks.

@JedWatson thoughts?

@wmertens it would be nice if we could do this for any mongoose hook and not just pre/post save. And note, that this keeps pushing [business] logic into the mongoose where we should instead be attempting to do this up in keystone. There has been some discussion about this in slack. That been said, I like your proposal for pre/post save hooks :=)

@webteckie Well, we can just pass this session context object to all the mongoose hooks, no? Would also simplify authorization, eg. just check the userlevel in the context object vs the current data…

@wmertens probably. For now I would issue a PR for your idea, if @JedWatson is alright with it. You don't have to break anything if you leave the _req_user alone.

btw, I would call the item property __session_context

No time for a PR right now, sorry, so anybody that feels up to it?

and my suggestion for this PR would support mongoose query pre and post middleware. not only for saveItem

Hi, any development about the feature suggested by @wmertens?
I'd be happy to help if needed, but first I would like to know some views from @JedWatson about this topic (maybe there's some dev already going on).

One more thing (maybe OT): I've been thinking about a clean solution to another big missing feature: contents localization/i18n. Creating a solid context object could be crucial to address the issue: imagine to set the language of an item instance in pre init hook, getting the language preference from the current request context.
I have this solution already working well using another context module set in pre routes middleware; but it works only for the public client routes: an internal keystone context is really necessary in order to get it working for the admin UI pages too.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

jacqueslareau picture jacqueslareau  Â·  5Comments

stennie picture stennie  Â·  5Comments

Twansparant picture Twansparant  Â·  5Comments

kamontat picture kamontat  Â·  5Comments

celiao picture celiao  Â·  4Comments