Git Product home page Git Product logo

ally's People

Contributors

artessan avatar bitkidd avatar bricklou avatar dependabot-preview[bot] avatar dkbay avatar elie-g avatar greenkeeper[bot] avatar haplifeman avatar hugomarisco avatar iamraphson avatar irwing-reza avatar julien-r44 avatar mcsneaky avatar mesteery avatar paul-nallet avatar romainlanz avatar romch007 avatar thetutlage avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ally's Issues

Ally and Offline/Refresh Token Mode

I'm wondering how one could set the driver to request an oAuth permanent refresh token (offline mode).

I couldn't find anything in the docs but they do mention getRefreshToken() which only returns null since the oAuth doesn't even request offline privileges.

Truecaller Driver

Why this feature is required (specific use-cases will be appreciated)?

Because of its value to most category of web application online these days. A TrueCaller Auth implementation will be a nice fit into the list of social login features this package currently supports.

Have you tried any other work arounds?

No

Are you willing to work on it with little guidance?

Yes

Session missing

I created an app with adonuxt. I created a facebook app and i get a very weird issue. When i login first time and facebook ask me if i want to authorize the app sessions are disappeared on callback. But if i try again and i have already authorized the app everything works great.
That's a very weird issue and i have no idea why this happens

Exception: E_OAUTH_STATE_MISMATCH (Ally 2.1.0)

Package version

"version": "4.1.0",
"adonis-version": "4.1.0",

@adonisjs/[email protected]
@adonisjs/[email protected]
@adonisjs/[email protected]
@adonisjs/[email protected]
@adonisjs/[email protected]
@adonisjs/[email protected]
@adonisjs/[email protected]
@adonisjs/[email protected]
@adonisjs/[email protected]
@adonisjs/[email protected]
@adonisjs/[email protected]

Node.js and npm version

NodeJS v10.9.0
npm 6.2.0

Sample Code (to reproduce the issue)

I have this exception when I try to access to Google API since I upgraded Ally to version 2.1.0.
This code works on the previous version (2.0.5)

OAuthException
E_OAUTH_STATE_MISMATCH: Oauth state mis-match

start/routes

  Route.get('auth/google', async ({ ally }) => {
    await ally.driver('google').redirect()
  })

  Route.get('authenticated/google', async ({ ally }) => {
    const user = await ally.driver('google').getUser()

    return user
  })

Microsoft Driver

How difficult would it be to create a driver for Microsoft login to enable users to login with ms credentials? It's an OAuth2 endpoint, so would I be able to copy a driver already created and modify for this?

Missing parameter clientId expected by oauth2 method as 1st parameter > when I login through facebook.

Prerequisites

We do our best to reply to all the issues on time. If you will follow the given guidelines, the turn around time will be faster.

  • Lots of raised issues are directly not bugs but instead are design decisions taken by us.
  • Make use of our forum, or discord server, if you are not sure that you are reporting a bug.
  • Ensure the issue isn't already reported.
  • Ensure you are reporting the bug in the correct repo.

Delete the above section and the instructions in the sections below before submitting

Package version

Node.js and npm version

Sample Code (to reproduce the issue)

BONUS (a sample repo to reproduce the issue)

Fully-featured example with API-only?

Would it be possible to get a full example using API only?

Ideally this would include the

  • redirect
  • callback
  • some kind of get method
  • protected api routes using the authentication

I'm having a few issues trying to flesh out the "basic" example and I'm not sure about best practices, so this would be a really nice reference.

Session is reset after redirecting from the handler of an Ally oauth callback

Brief Description

The session seems to be reset after redirecting from the handler for an Ally oauth callback.

Any other response does not reset the session as far as I can tell.

Sample Code

I created a full repo to demo this issue:
https://github.com/SidneyNemzer/adonis-redirect-bug

Install instructions are in the README

This might be related to adonisjs/core#771? However I don't think that issue involved Ally, and I have been unable to reproduce this bug without Ally.

set state value when redirect

Why this feature is required (specific use-cases will be appreciated)?

Frontend is nuxt, and backend is adonisjs.

What I want to do is, when user click the login button once, frontend nuxt and backend adonisjs is logged in at the same time.

When users click the login button,
In the backend Ally run oauth process and backend will be logged in.
But my frontend nuxt is not logged in not yet.
Ally have to send a token which is delivered from google etc.

In the frontend, to make nuxt auth logged in, I wish that nuxt will receive the token from adonis ally which is same with google's token.
At this step, nuxt-auth checks the state value is same.
At the first time, nuxt-auth's oauth make a state value using nanoid(), or we can set custom state value.

So we have to send a token which is generated by nuxt-auth.
So we need to set the state value when ally's redirect.

Are you willing to work on it with little guidance?

Below is simple code to suggest

SomeController.js

async redirect({ally, params, request}) {
    const req = request.all()
    await ally.driver('google').redirect(req.state) 
}

ally/src/Authenticator.js

async redirect (custom_state = null) {
    let state = null

    if (!this._isStateless && this._driverInstance.supportStates) {
      state = (custom_state)?custom_state:uuid()
      this._response.cookie('oauth_state', state, this._cookieOptions)
    }

    const url = await this.getRedirectUrl(state)
    this._response.status(302).redirect(url)
  }

or state method

await ally.driver('google').state(req.state).redirect()

Problem with getting user data via google driver

Hi @thetutlage

To begin with, really appreciate your work on AdonisJs ecosystem.

I (more or less) copied the example from https://adonisjs.com/docs/4.0/social-auth:

async handleGoogleAuthRedirect({ally, auth}) {
	try {
		const googleUser = await ally.driver('google').getUser();

		// user details to be saved
		const userDetails = {
			email: googleUser.getEmail(),
			token: googleUser.getAccessToken(),
			login_source: 'google',
		};

		// search for existing user
		const whereClause = {
			email: googleUser.getEmail(),
		};

		const user = await User.findOrCreate(whereClause, userDetails);
		await auth.login(user);

		return 'Logged in';
	} catch (error) {
		return JSON.stringify(error);
	}
}

I adjusted it for google, generated OAuth Client Id in Developer Console, declared proper routes and placed the credentials in the env file. However, I keep getting the following response:

{
	"name": "HTTPError",
	"host": "www.googleapis.com",
	"hostname": "www.googleapis.com",
	"method": "GET",
	"path": "/plus/v1/people/me",
	"protocol": "https:",
	"url": "https://www.googleapis.com/plus/v1/people/me",
	"statusCode": 403,
	"statusMessage": "Forbidden",
	"headers": {
		"vary": "Origin, X-Origin",
		"content-type": "application/json; charset=UTF-8",
		"content-encoding": "gzip",
		"date": "Tue, 14 Aug 2018 13:32:03 GMT",
		"expires": "Tue, 14 Aug 2018 13:32:03 GMT",
		"cache-control": "private, max-age=0",
		"x-content-type-options": "nosniff",
		"x-frame-options": "SAMEORIGIN",
		"x-xss-protection": "1; mode=block",
		"server": "GSE",
		"alt-svc": "quic=\":443\"; ma=2592000; v=\"44,43,39,35\"",
		"connection": "close",
		"transfer-encoding": "chunked"
	}
}

I did some research and discovered that authentication works correctly because _getUserProfile function in src/Driver/Google.js receives an accessToken. I even used it for url https://www.googleapis.com/oauth2/v1/userinfo and got the correct response with user data.

I presume the current url https://www.googleapis.com/plus/v1/people/me doesn't work anymore for OAuth. Am I correct? Or maybe I am doing something wrong?

Thanks in advance.

Package version

2.0.5

Node.js and npm version

v9.11.2

IoC extend not working (custom driver)

Hi

I try to extend Ally with my own driver. I followed the comment in #32, but without success.
Currently the start/hooks.js file contains the following code:

const { ioc } = require('@adonisjs/fold');
const { hooks } = require('@adonisjs/ignitor');

hooks.after.providersBooted(() => {
    ioc.extend('Adonis/Addons/Ally', 'corpid', function() {
      return require('../app/Extensions/AllyCorpid');
    });
});

But when I try to redirect to the authorize page using the following code...

async redirect ({ ally }) {
    await ally.driver('corpid').redirect()
}

... i get an «E_INVALID_PARAMETER: corpid is not a valid ally driver» error in my browser window (but no errors in the node console).
The driver itself (AllyCorpid.js) is inspired by the 1st party facebook driver and looks almost identical.
Btw. I also tried to return an instantiated object in hooks.js - didn't work either.

Facebook public_profile fields

Hi, learning the new Ally authentication system, and I was wondering how to access other fields like verified, first_name, last_name etc returned in a public profile?
Currently Ally uses FB graph v2.1. Current version is 2.8. Not sure it will matter but just to let you know
And one other thing: in driver/Facebook line 211 and 213 are duplicates.

Can't set additional parameter on baseUrl

Hello, I plan to make a custom driver to login into Microsoft OAuth

Now, I want to setup baseUrl like this

get baseUrl() {
    return `https://login.microsoftonline.com/${this.tenantId}/oauth2/v2.0/`
}

I have set tenantId in constructor after super(config.clientId, config.clientSecret, config.headers)

this.tenantId = config.tenantId || 'common';

but it returned as undefined value

because of this
https://github.com/adonisjs/adonis-ally/blob/3c8697f7e0281f5ebe2903426a20c8bb8d24cace/src/Schemes/OAuth2.js#L99

Sending additional parameters to Facebook

My application requires that the user allows email permission so I would like to show an error and a button to rerequest permissions through Facebook which is usually achievable using auth_type=rerequest however I am unable to find the proper way to add this parameter with Ally.

I found that this code adds the parameter to the url but Facebook just throws an error as soon as I add it so it can't be the right way to do it.

const driver = request.ally.driver('facebook')

driver._driverInstance._redirectUriOptions.auth_type = 'rerequest'

yield driver.redirect()
{
   "error": {
      "message": "",
      "type": "OAuthException",
      "code": 100,
      "fbtrace_id": "CpcKgSUPq8L"
   }
}

Any help is much appreciated!

Support for apple sign in

Prerequisites

We do our best to reply to all the issues on time. If you will follow the given guidelines, the turn around time will be faster.

Consider an RFC

Please create an RFC instead, if

  • Feature introduces a breaking change
  • Demands lots of time and changes in the current code base.

Delete the above section and the instructions in the sections below before submitting

Why this feature is required (specific use-cases will be appreciated)?

I submitted my app to app store review and app store want me to add apple sign in, since i am using google and facebook sign in.

Have you tried any other work arounds?

I have looked for couple of solution but all ends with removing adonis from system, which is not possible for me.

Are you willing to work on it with little guidance?

no

Certain driver name can't be resolved when extending.

I have multiple OAuth drivers for Github as I have two different consumers, one for a cli tool and one for a web app, each one has a different redirect URL.

When I register my GithubCLIDriver with the name githubCLI & attempt to resolve it through AllyManager.driver('githubCLI'); I get thrown a E_INVALID_PARAMETER: githubCLI is not a valid ally driver error.

If I swap that name to foo it resolves successfully.

It appears for some reason that the container is having a hard time resolving with the name githubCLI

Edit: It looks like the IOC has an issue with resolving names with any capital letters in it, I assume this isn't a Ally issue and more of an IOC issue so I'll close this.

Package version

2.1.3

Node.js and npm version

Node: 10.15.3
Npm: 6.4.1

Sample Code

Failing code

hooks.before.providersBooted(() => {
  const AllyManager = require('@adonisjs/ally/src/AllyManager');
  const Github = require('../app/SocialDrivers/GithubCLIDriver');

  AllyManager.extend('githubCLI', Github);
  console.log(AllyManager.driver('githubCLI')); // throws here
});

Working code

hooks.before.providersBooted(() => {
  const AllyManager = require("@adonisjs/ally/src/AllyManager");
  const Github = require('../app/SocialDrivers/GithubCLIDriver');

  AllyManager.extend('foo', Github);
  console.log(AllyManager.driver('foo')); //successfully prints driver
});

Use select_account prompt option

At least in the google provider, I used to be able to add a "prompt" field in my passport js request to google, in the same object as the "scopes" field. If I set this as prompt: 'select_account' it allowed me to force the user to select their account every time they logged in, not defaulting to a previously selected one.

Is there any way to do this with ally?

Register AllyManager as a manager in Ioc?

Hey I've just been looking at this and best way to extend with my own driver. I saw that there is an extend method, and in adonis-fold there's an extend method - however it doesn't work currently as AllyManager isn't registered in the Ioc as a manager. Is there any specific reason for this?

Instructions for extending

This looks great.

Can you share some instructions for extending adonis-ally to create other oauth2 providers?

Do you recommend doing this in the Http.onStart listener?

Thanks.

getProvider() needed

In every Oauth library I've used (passport, omniauth, Ueberauth) the provider could be returned from the query. I think its passed through the oauth2 state parameter.

The most important reason for this that the callback handler can be generic and handle all provider redirects, which in turn means you can register the same callback at all providers. Currently not only do I have to create an unique callback for each provider but I also have to register the unique callbacks at all providers.

Linking accounts

Hello,

I am trying to create a website which only allows users to log with social accounts. (No registration, Facebook and Twitter login only for now.) I also want users can merge their Facebook and Twitter accounts into one if they want to. Once they merge/link their social accounts, the app will recognize the user, regardless which account the user login with. But I couldn't figure out how to accomplish this without a local user system. I will also need local accounts for administration on the other hand.. Thinking it drives me crazy..

Can anyone suggest me anything?

Thanks.

Ability to add custom drivers from code

I need to add some drivers to my application that are not already included. While I can pull request the ones I make I think it would be a good idea to allow people to load their own driver implementations into Ally through a bootstrapping process or a configuration setting for ally that will load drivers via a folder/namespace.

Let me know if this is something that you would consider, and if it is I can submit a pull request if you like.

How create currentUser with Relations?

My User model has id, name and permissions as Relations

const user = yield User
  .query()
  .with('permissions') 
  .fetch()
{
  "id": 1,
  "name": "Alex"
  "permissions": [/* ... */]
}

But after login request.currentUser has no permissions property. How create currentUser object with Relations? For example:

request.auth.loginViaId(id).with('permissions') 

Best place to store Ally extend code

Hi there,

I am working on a Slack integration that I am happy to submit to the core project once completed.

Until that point I am wondering, where is the best place to put the Ally.extendcode?

I have tried placing it in a service provider but it seemed not enough of the application was ready.
Currently it is sitting in bootstrap/http.js just before the server starts. This works but is obviously very hacky.

Thank you for your time and I look forward to contributing 😄

How do I override the toJSON() method for my model?

My model has a property, the property holds a string in json format. I'd like toJSON() method parse her.
I tried to do this, but it does not work

class Option extends Model {
  toJSON () {
    const json = super.toJSON()
    if (typeof json.value === 'string')
      json.value = JSON.parse(json.value)
    return json
  }

LinkedIn login not working (api v2)

LinkedIn login not working for api v2

The LinkedIn driver uses the v1 version of the API. And new applications do not work with this version of api.

All new applications created on the LinkedIn Developer Platform as of January 14, 2019 can use LinkedIn's v2 APIs. Starting May 1, 2019, LinkedIn will deprecate use of its v1 APIs. If your developer application currently depends on LinkedIn v1 APIs, see the frequently asked questions below before migrating to LinkedIn v2 APIs.

Source: https://docs.microsoft.com/en-us/linkedin/consumer/integrations/self-serve/migration-faq?context=linkedin/consumer/context

Get AllyUser using social access_token

My case:
The client is mobile app (android, ios) using facebook sdk and firebase sdk to login and get access_token from facebook and google then post to adonis server to verify login
Can add support adonis-ally to get ally user by using existing access_token?

const socialToken = request.input('social_token')
const facebook = ally.driver('facebook')

const allyUser = await facebook.getUserByToken(socialToken)

const user = await User.findOrCreate({ social_id: allyUser.id, social_type: 'facebook' })
const token= await auth.loginVia(user)
response.json({
  token,
  user: user.toJSON()
})

Ally References Config option that doesn't exist

Cause

The codebase makes use of a config option ( 'app.cookie' ) in the config/app.js file of an adonis-framework installation which doesn't exist there by causing unexpected behavior when trying to validate the "state" parameter via the cookie entry "oauth_state" when using the Instagram driver.

Please i would like something to be done about this

Package version

v2.1.x

Node.js and npm version

v10.5 / v6.0

Sample Code (to reproduce the issue)

Config.merge('app.cookie', {
     sameSite:false,
     httpOnly:true
})

BONUS (a sample repo to reproduce the issue)

Extend Ally User Fields

I am trying to use a custom OAuth. I am able to get the details of the user but I don't receive email from the OAuth provider. I get different data. How can i extend ally user fields to match my data?

Thanks

[feature] Add CSRF protection as per RFC 6749

This provider is working great.

It would be nice if the provider enforced the use of CSRF protection as defined by RFC 6749.

It recommends the use of the state parameter in the authorization url.

The client MUST implement CSRF protection for its redirection URI.
This is typically accomplished by requiring any request sent to the
redirection URI endpoint to include a value that binds the request to
the user-agent's authenticated state (e.g., a hash of the session
cookie used to authenticate the user-agent). The client SHOULD
utilize the "state" request parameter to deliver this value to the
authorization server when making an authorization request.

What do you think about having some sort of support for this?

How to register an additional driver?

I would like to add support for VK authorization. For this, I need the appropriate driver. How to add this? I have to make a fork of this repository, if there are any built-in tools for this, say:

ally.registerDriver('vk', {
  baseUrl : '...',
  authorizeUrl : '...',
  accessTokenUrl : '...',
  // ...
})

Google authentication not setting session

Ally Google authentication callback doesn't seem to set the session, hence auth check always returns false.

I have tried changing the session type to file as well, with no success.

NOTE: Ally works just as expected with facebook. However, this:

const User = use('App/Models/User');

..

async callback({ ally, auth, response, session }) {
    try {
        const providerUser = await ally.driver('google').getUser();

        const userDetails = {
            name: providerUser.getNickname() || null,
            email: providerUser.getEmail() || null,
            profile_pic: providerUser.getAvatar() || null,
        }

        const whereClause = {
            email: providerUser.getEmail()
        }

        const user = await User.findOrCreate(whereClause, userDetails);

        await auth.login(user);

        /*
          Session is definitely set in this line with both providers,
          because this line shows the correct user details
        */
        console.log(auth.user.name); /* Logs the name of the google/facebook user */

        return response.route('login')
        /* I have tried response.redirect('back') as well. Same result. */

        /*
          Response.redirect('back') takes the user back to the login page in facebook's
          case. However, the user is taken back to root (/) in google's case
        */
    } catch (error) {
        session.flash({
            oauth: {
                type: 'error',
                text: 'Failed to login with provider'
            }
        });
        return response.route('login');
    }
}

does not seem to work with google. Works perfectly with facebook though

Extending AllyManager to add more drivers

I've been trying to add a driver to Ally, however it still doesn't seem to get it.

start/hooks.js

const { hooks } = require('@adonisjs/ignitor')
const { ioc } = require('@adonisjs/fold')
const pinterest = use('App/Oauth/pinterest')

hooks.after.providersBooted(() => {
  const Validator = use('Validator')
  const Database = use('Database')
  const existsFn = async (data, field, message, args, get) => {
    const value = get(data, field)
    if (!value) {
      /**
       * skip validation if value is not defined. `required` rule
       * should take care of it.
       */
      return
    }

    const [table, column] = args
    const row = await Database.table(table).where(column, value).first()

    if (!row) {
      throw message
    }
  }

  Validator.extend('exists', existsFn)
})

hooks.after.providersRegistered(() => {
  ioc.extend('Adonis/Addons/Ally', 'pinterest', pinterest);
})

My pinterest file is simply a copy of the facebook oauth, in app/Oauth/pinterest.js

'use strict'

/*
 * adonis-ally
 *
 * (c) Harminder Virk <[email protected]>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
*/

const loc = '../../node_modules/@adonisjs/ally/src/Drivers/'

const got = require('got')
const _ = require('lodash')



const CE = require(loc + '../Exceptions')
const OAuth2Scheme = require(loc + '../Schemes/OAuth2')
const AllyUser = require(loc + '../AllyUser')
const utils = require(loc + '../../lib/utils')

/**
 * Facebook driver to authenticate a user using
 * OAuth2 scheme.
 *
 * @class Facebook
 * @constructor
 */
class Pinterest extends OAuth2Scheme {
    constructor(Config) {
        const config = Config.get('services.ally.pinterest')

        utils.validateDriverConfig('pinterest', config)
        utils.debug('pinterest', config)

        super(config.clientId, config.clientSecret, config.headers)

        /**
         * Oauth specific values to be used when creating the redirect
         * url or fetching user profile.
         */
        this._scope = this._getInitialScopes(config.scope)
        this._fields = this._getInitialFields(config.fields)
        this._redirectUri = config.redirectUri
        this._redirectUriOptions = Object.assign({ response_type: 'code' }, config.options)
    }

    /**
     * Injections to be made by the IoC container
     *
     * @attribute inject
     *
     * @return {Array}
     */
    static get inject() {
        return ['Adonis/Src/Config']
    }

    /**
     * Scope seperator for seperating multiple
     * scopes.
     *
     * @attribute scopeSeperator
     *
     * @return {String}
     */
    get scopeSeperator() {
        return ','
    }

    /**
     * Base url to be used for constructing
     * facebook oauth urls.
     *
     * @attribute baseUrl
     *
     * @return {String}
     */
    get baseUrl() {
        return 'https://graph.pinterest.com/v2.1'
    }

    /**
     * Relative url to be used for redirecting
     * user.
     *
     * @attribute authorizeUrl
     *
     * @return {String} [description]
     */
    get authorizeUrl() {
        return 'oauth/authorize'
    }

    /**
     * Relative url to be used for exchanging
     * access token.
     *
     * @attribute accessTokenUrl
     *
     * @return {String}
     */
    get accessTokenUrl() {
        return 'oauth/access_token'
    }

    /**
     * Returns initial scopes to be used right from the
     * config file. Otherwise it will fallback to the
     * commonly used scopes.
     *
     * @method _getInitialScopes
     *
     * @param   {Array} scopes
     *
     * @return  {Array}
     *
     * @private
     */
    _getInitialScopes(scopes) {
        return _.size(scopes) ? scopes : ['email']
    }

    /**
     * Returns the initial fields to be used right from the
     * config file. Otherwise it will fallback to the
     * commonly used fields.
     *
     * @method _getInitialFields
     *
     * @param   {Array} fields
     *
     * @return  {Array}
     *
     * @private
     */
    _getInitialFields(fields) {
        return _.size(fields) ? fields : ['name', 'email', 'gender', 'verified', 'link']
    }

    /**
     * Returns the user profile as an object using the
     * access token.
     *
     * @method _getInitialFields
     *
     * @param   {String} accessToken
     * @param   {Array} [fields]
     *
     * @return  {Object}
     *
     * @private
     */
    async _getUserProfile(accessToken, fields) {
        fields = _.size(fields) ? fields : this._fields
        const profileUrl = `${this.baseUrl}/me?access_token=${accessToken}&fields=${fields.join(',')}`

        const response = await got(profileUrl, {
            headers: {
                'Accept': 'application/json'
            },
            json: true
        })

        return response.body
    }

    /**
     * Returns the redirect url for a given provider.
     *
     * @method getRedirectUrl
     *
     * @param  {Array} scope
     *
     * @return {String}
     */
    async getRedirectUrl(scope) {
        scope = _.size(scope) ? scope : this._scope
        return this.getUrl(this._redirectUri, scope, this._redirectUriOptions)
    }

    /**
     * Parses provider error by fetching error message
     * from nested data property.
     *
     * @method parseProviderError
     *
     * @param  {Object} error
     *
     * @return {Error}
     */
    parseProviderError(error) {
        const parsedError = _.isString(error.data) ? JSON.parse(error.data) : null
        const message = _.get(parsedError, 'error.message', error)
        return CE.OAuthException.tokenExchangeException(message, error.statusCode, parsedError)
    }

    /**
     * Parses the redirect errors returned by facebook
     * and returns the error message.
     *
     * @method parseRedirectError
     *
     * @param  {Object} queryParams
     *
     * @return {String}
     */
    parseRedirectError(queryParams) {
        return queryParams.error_message || 'Oauth failed during redirect'
    }

    /**
     * Returns the user profile with it's access token, refresh token
     * and token expiry.
     *
     * @method getUser
     *
     * @param {Object} queryParams
     * @param {Array} [fields]
     *
     * @return {Object}
     */
    async getUser(queryParams, fields) {
        const code = queryParams.code

        /**
         * Throw an exception when query string does not have
         * code.
         */
        if (!code) {
            const errorMessage = this.parseRedirectError(queryParams)
            throw CE.OAuthException.tokenExchangeException(errorMessage, null, errorMessage)
        }

        const accessTokenResponse = await this.getAccessToken(code, this._redirectUri, {
            grant_type: 'authorization_code'
        })

        const userProfile = await this._getUserProfile(accessTokenResponse.accessToken, fields)

        const user = new AllyUser()
        const avatarUrl = `${this.baseUrl}/${userProfile.id}/picture?type=normal`

        /**
         * Build user
         */
        user
            .setOriginal(userProfile)
            .setFields(
                userProfile.id,
                userProfile.name,
                userProfile.email,
                userProfile.name,
                avatarUrl
            )
            .setToken(
                accessTokenResponse.accessToken,
                accessTokenResponse.refreshToken,
                null,
                Number(_.get(accessTokenResponse, 'result.expires'))
            )

        return user
    }
}

module.exports = Pinterest

However I still get an error E_INVALID_PARAMETER: pinterest is not a valid ally driver

There isn't much documentation for this at all, but based on it not erroring out I know it is at least the right syntax.

microsft account auth

hello thanks for your aplication is posible add driver for microsoft account (outlook live email, )

thanks

Access token expiration being set to NaN

According to the OAuth2 spec, the expiration field is optional in the access token response.

(Almost) all Oauth2 drivers include this line:
https://github.com/adonisjs/adonis-ally/blob/develop/src/Drivers/Facebook.js#L258

Making the token expiration part of the AllyUser being set to Number(undefined) === NaN where I'd expect it to be null.

I propose a fix either in the drivers or in the AllyUser class to make sure this field is null when not provided by the third party.

I'm happy to create a PR after a decision around where to include the guard.

Facebook Login Issue [appsecret_proof required]

Hello All,

I am getting this error using facebook provider with method getUserByToken. My app in Facebook Require App Secret

OAuth Facebook Platform "invalid_request" API calls from the server require an appsecret_proof argument

I am using [email protected], I looked at the code and I dont see any reference its passing appsecret_proof with the call.

Could someone help me into right direction?

const userInfo = await ally.driver('facebook').getUserByToken(accessToken)

[bug] Auth Twitter

Hello, I do not know if I can call BUG anymore the following is occurring:

When you authenticate with Twitter by using the user.getName () and user.getNickname (), or user.toJSON () method, Ally is changing the name with the user name.

Ex.:
Original:
Name: Carlos Eduardo
Username: duducp

Return of Ally:
Name: duducp
Username: Carlos Eduardo

Facebook scope for birthday not working as expected

Package version

v.2.1.3

Node.js and npm version

Node: 10.12.0
Npm: 6.9.0

Sample Code (to reproduce the issue)

According to the docs to get birthday we pass in birthday but that throws an error
await ally
.driver('facebook')
.scope(['email', 'birthday'])
.redirect();
Screenshot 2020-05-12 at 20 27 18

I changed the code to according to facebook oAuth scope... This doesn't throw an error but from the payload returned I dont get to see the birthday.
await ally
.driver('facebook')
.scope(['email', 'user_birthday'])
.redirect();

BONUS (a sample repo to reproduce the issue)

Exception: E_OAUTH_STATE_MISMATCH (Ally 2.1.3)

Package version

"@adonisjs/ace": "^5.0.8",
"@adonisjs/ally": "^2.1.3",
"@adonisjs/auth": "^3.0.7",
"@adonisjs/bodyparser": "^2.0.5",
"@adonisjs/cors": "^1.0.7",
"@adonisjs/fold": "^4.0.9",
"@adonisjs/framework": "^5.0.9",
"@adonisjs/ignitor": "^2.0.8",
"@adonisjs/lucid": "^6.1.3",
"@adonisjs/session": "^1.0.27",
"@adonisjs/shield": "^1.0.8",
"pg": "^7.17.1"

Node.js and npm version

node -v = v12.13.1
npm -v = 6.12.1

Sample Code (to reproduce the issue)

I have this exception when I try to access to Google API since I upgraded Ally to version 2.1.3.
This code works on the previous version (2.1.1)

  • start/routes.js
Route.get('login/google', 'LoginController.redirect')
Route.get('google/callback', 'LoginController.callback')
  • app/Controllers/Http/LoginController
'use strict'
const User = use('App/Models/User.js')

class LoginController {
  async redirect ({ ally }){
    await ally.driver('google').redirect()
  }

  async callback ({ ally, auth }) {
    try {
      const gUser = await ally.driver('google').getUser();

      const userDetails = {
        email: gUser.getEmail(),
        token: gUser.getAccessToken(),
        login_source: 'google'

      };

      const whereClause = {
        email: gUser.getEmail()
      };

      const user = await User.findOrCreate(whereClause, userDetails)
      await auth.login(user)
    } catch (e) {
      console.log(e);
      return 'Unable to authenticate. Please contact support'
    }
  }
}

module.exports = LoginController

How to dynamically set redirectUri for the service?

Here is a simple example of my current code:

class LoginController {

  // /login/facebook
  async redirect ({ally, params, auth, response, request}) {
    return await ally.driver('facebook').redirect()
  }

  // /authenticated/facebook
  async handleCallback ({ ally, auth, response, params, request }) {
      const user = await ally.driver('facebook').getUser()
      await auth.loginViaId(user.id)
      response.redirect(/* WHERE? */)
  }
}

I would like to be able to convey certain arbitrary parameters that would be set up for redirectUri. For example:

class LoginController {

  // /login/facebook?returnTo=custom-value
  async redirect ({ally, params, auth, response, request}) {
    return await ally.driver('facebook').redirect({
      redirectUriQuery: request.get()
    })
  }

  // /authenticated/facebook?returnTo=custom-value
  async handleCallback ({ ally, auth, response, params, request }) {
      const user = await ally.driver('facebook').getUser()
      await auth.loginViaId(user.id)
      response.redirect(request.get().returnTo)
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.