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

Keeping context between calbacks #94

Open
willstott101 opened this issue Jan 24, 2022 · 3 comments
Open

Keeping context between calbacks #94

willstott101 opened this issue Jan 24, 2022 · 3 comments

Comments

@willstott101
Copy link
Contributor

We have a get-user-repo-access-info procedure which is asynchronous - we run this in the authenticate callback as passed into the Git constructor. We do this to deny access to users before this library even looks for a git repo to use. However when we then get to the push event listener we're struggling to see how we can equate the original request with this specific callback. There is no shared state passed into the listener.

Would you be willing to help us rectify this? Honestly I'd be fine with just adding http.IncomingMessage to the GitAuthenticateOptions as req - I can then just add a property to that object 🤷

It looks as though you've maybe kept the authenticate callback to accept the bare minimum of information though - if there's a specific reason for that perhaps we could add an empty context object to the authenticate callback which can then be passed to later event handlers. Avoiding giving the authenticate method any additional data to be mis-understood or used.

Thanks for the very helpful library, happy to open a PR for this, just wanted an idea of what is more likely to be merged.

@gabrielcsapo
Copy link
Owner

I think adding a context object specifically for passing around data would be great.

I am hesitant to just add this to a req object as that can change.

I am totally cool for this to be added, if you open a PR I can help shepherd it through.

@willstott101
Copy link
Contributor Author

Ok, working on this I see the root of the issue is that a service call is performed in a separate request to authentication. So the server will have to authenticate twice. I think that's fine and users of the lib can cache their auth info if they like. But I'm ending up doing a bit of a refactor to make the request flow a bit clearer to me.

I've simplified the possible authentication callback signatures to:

authenticate?: (options: GitAuthenticateOptions) => Promise<T> | T;

(and simplified the options.user callable to: getUser: () => Promise<[string | undefined, string | undefined]>;)
as those changes have really helped implementation - and helped me to convince myself the implementation is correct.

So usage looks something like this:

const repos = new Git<number>(repoDir, {
  autoCreate: true,
  authenticate: async (options) => {
    const [username, password] = await options.getUser(); // throws on failure rather than writing to res
    if (username !== "me" || password !== "foo") {
      throw new Error("username or password incorrect");
    }
    return { a: 42, username: username };
  },
});
repos.on("push" ({ context }) => context.a === 42);

@willstott101
Copy link
Contributor Author

Opened a PR of my WIP - seems to work fine for me but I'd like to add more tests

#97

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

2 participants