UNPKG

adonis6_ally_yandex

Version:
159 lines (158 loc) 5.01 kB
/* |-------------------------------------------------------------------------- | Ally Yandex Oauth driver |-------------------------------------------------------------------------- | | This is an Ally Oauth driver for authenticating users via Yandex. | */ import { Exception } from '@poppinss/utils'; import { Oauth2Driver } from '@adonisjs/ally'; /** * Yandex driver to login user via Yandex */ export class YandexDriver extends Oauth2Driver { config; accessTokenUrl = 'https://oauth.yandex.ru/token'; authorizeUrl = 'https://oauth.yandex.ru/authorize'; userInfoUrl = 'https://login.yandex.ru/info'; userAvatarUrl = 'https://avatars.yandex.net/get-yapic'; userAvatarSize = 'islands-200'; /** * The param name for the authorization code */ codeParamName = 'code'; /** * The param name for the error */ errorParamName = 'error'; /** * Cookie name for storing the "yandex_oauth_state" */ stateCookieName = 'yandex_oauth_state'; /** * Parameter name to be used for sending and receiving the state * from yandex */ stateParamName = 'state'; /** * Parameter name for defining the scopes */ scopeParamName = 'scope'; /** * Scopes separator */ scopesSeparator = ' '; constructor(ctx, config) { super(ctx, config); this.config = config; /** * Extremely important to call the following method to clear the * state set by the redirect request */ this.loadState(); } /** * Configuring the redirect request with defaults */ configureRedirectRequest(request) { /** * Define user defined scopes or the default one's */ request.scopes(this.config.scopes || ['login:email', 'login:info', 'login:avatar']); /** * Set "response_type" param */ request.param('response_type', 'code'); } /** * Returns the HTTP request with the authorization header set */ getAuthenticatedRequest(url, token) { const request = this.httpClient(url); request.header('Authorization', `OAuth ${token}`); request.header('Accept', 'application/json'); request.parseAs('json'); return request; } /** * Fetches the user info from the Yandex API */ async getUserInfo(token, callback) { const url = this.config.userInfoUrl || this.userInfoUrl; const userAvatarUrl = this.config.userAvatarUrl || this.userAvatarUrl; const userAvatarSize = this.config.userAvatarSize || this.userAvatarSize; const request = this.getAuthenticatedRequest(url, token); if (typeof callback === 'function') { callback(request); } const body = await request.get(); const avatarUrl = `${userAvatarUrl}/${body.default_avatar_id}/${userAvatarSize}`; return { id: body.id, nickName: body.login, name: body.real_name, avatarUrl: body.default_avatar_id ? avatarUrl : '', original: body, }; } /** * Fetches the user email from the Yandex API */ async getUserEmail(token, callback) { const url = this.config.userInfoUrl || this.userInfoUrl; const request = this.getAuthenticatedRequest(url, token); if (typeof callback === 'function') { callback(request); } const body = await request.get(); if (!body.default_email) { throw new Exception('Cannot request user email. Make sure you are using the "login:email" scope'); } return body.default_email; } /** * Find if the current error code is for access denied */ accessDenied() { const error = this.getError(); if (!error) { return false; } return error === 'access_denied'; } /** * Returns details for the authorized user */ async user(callback) { const token = await this.accessToken(callback); const user = await this.getUserInfo(token.token, callback); const email = await this.getUserEmail(token.token, callback); return { ...user, email: email, emailVerificationState: 'unsupported', token: token, }; } /** * Finds the user by the access token */ async userFromToken(token, callback) { const user = await this.getUserInfo(token, callback); const email = await this.getUserEmail(token, callback); return { ...user, email: email, emailVerificationState: 'unsupported', token: { token, type: 'bearer' }, }; } } /** * The factory function to reference the driver implementation * inside the "config/ally.ts" file. */ export function YandexDriverService(config) { return (ctx) => new YandexDriver(ctx, config); }