function mailru(router, config = {}) {
  const {
    client_id,
    client_secret,
    path = '/auth/mailru',
    scope,
    error = (ctx, err, description) => {
      throw new Error(description)
    },
    finish = /* async */ (ctx, token, user /* next */) => {
      ctx.session.token = token
      ctx.session.user = user
      ctx.redirect('/')
    },
    session,
  } = config

  if (!client_id) {
    console.warn('[mailru] No client id - the dialog won\'t work.')
  }
  if (!client_secret) {
    console.warn('[mailru] No client secret - the redirect won\'t work.')
  }

  const start = async (ctx) => {
    const state = Math.floor(Math.random() * 10000)
    ctx.session.state = state
    const redirect_uri = getRedirect(ctx, path, state)
    const u = mailruDialogUrl({
      redirect_uri,
      client_id,
      scope,
      state,
    })
    ctx.redirect(u)
  }
  const startMw = session ? [session, start] : [start]
  router.get(path, ...startMw)

  const redirect = async (ctx, next) => {
    const state = ctx.query.state
    if (state != ctx.session.state) {
      throw new Error('The state is incorrect.')
    }
    const redirect_uri = getRedirect(ctx, path, state)
    ctx.session.state = null
    if (ctx.query.error) {
      const { error: e, error_description } = ctx.query
      await error(ctx, e, error_description, next)
      return
    }
    if (!ctx.query.code) throw new Error('Code Not Found.')

    const token = await exchange({
      client_id,
      client_secret,
      code: ctx.query.code,
      redirect_uri,
    })
    const data = await getInfo(token, client_id, client_secret)
    await finish(ctx, token, data, next)
  }
  const redirectMw = session ? [session, redirect] : [redirect]
  router.get(`${path}/redirect`, ...redirectMw)
}
/**
 * The Mail.Ru OAuth Login Routes For The Idio Web Server.
 * @param {import('koa-router')} [router] The router instance.
 * @param {Config} [config] Options for the program.
 * @param {string} config.client_id The app's client id.
 * @param {string} config.client_secret The app's client secret.
 * @param {string} [config.path="/auth/mailru"] The server path to start the login flaw and use for redirect (`${path}/redirect`). Default `/auth/mailru`.
 * @param {string} [config.scope="r_liteprofile"] The scope to ask permissions for. Default `r_liteprofile`.
 * @param {(ctx, token, user) => {}} [config.finish="setSession; redirect;"] The function to complete the authentication that receives the token and the data about the user, such as name and id. The default function redirects to `/`. Default `setSession; redirect;`.
 * @param {(ctx, error, error_description, next) => {}} [config.error="throw;"] The function to be called in case of error. If not specified, the middleware will throw an internal server error. Default `throw;`.
 * @param {Middleware} [config.session] The configured session middleware in case the `session` property is not globally available on the context.
 */
The Mail.Ru OAuth Login Routes For The Idio Web Server.
The Mail . Ru OAuth Login Routes For The Idio Web Server .
function mailru(router, config = {}) {
  const {
    client_id,
    client_secret,
    path = '/auth/mailru',
    scope,
    error = (ctx, err, description) => {
      throw new Error(description)
    },
    finish =  (ctx, token, user ) => {
      ctx.session.token = token
      ctx.session.user = user
      ctx.redirect('/')
    },
    session,
  } = config
  if (!client_id) {
    console.warn('[mailru] No client id - the dialog won\'t work.')
  }
  if (!client_secret) {
    console.warn('[mailru] No client secret - the redirect won\'t work.')
  }
  const start = async (ctx) => {
    const state = Math.floor(Math.random() * 10000)
    ctx.session.state = state
    const redirect_uri = getRedirect(ctx, path, state)
    const u = mailruDialogUrl({
      redirect_uri,
      client_id,
      scope,
      state,
    })
    ctx.redirect(u)
  }
  const startMw = session ? [session, start] : [start]
  router.get(path, ...startMw)
  const redirect = async (ctx, next) => {
    const state = ctx.query.state
    if (state != ctx.session.state) {
      throw new Error('The state is incorrect.')
    }
    const redirect_uri = getRedirect(ctx, path, state)
    ctx.session.state = null
    if (ctx.query.error) {
      const { error: e, error_description } = ctx.query
      await error(ctx, e, error_description, next)
      return
    }
    if (!ctx.query.code) throw new Error('Code Not Found.')
    const token = await exchange({
      client_id,
      client_secret,
      code: ctx.query.code,
      redirect_uri,
    })
    const data = await getInfo(token, client_id, client_secret)
    await finish(ctx, token, data, next)
  }
  const redirectMw = session ? [session, redirect] : [redirect]
  router.get(`${path}/redirect`, ...redirectMw)
}
function mailru ( router , config = { } ) { const { client_id , client_secret , path = '/auth/mailru' , scope , error = ( ctx , err , description ) => { throw new Error ( description ) } , finish = ( ctx , token , user ) => { ctx . session . token = token ctx . session . user = user ctx . redirect ( '/' ) } , session , } = config if ( ! client_id ) { console . warn ( '[mailru] No client id - the dialog won\'t work.' ) } if ( ! client_secret ) { console . warn ( '[mailru] No client secret - the redirect won\'t work.' ) } const start = async ( ctx ) => { const state = Math . floor ( Math . random ( ) * 10000 ) ctx . session . state = state const redirect_uri = getRedirect ( ctx , path , state ) const u = mailruDialogUrl ( { redirect_uri , client_id , scope , state , } ) ctx . redirect ( u ) } const startMw = session ? [ session , start ] : [ start ] router . get ( path , ... startMw ) const redirect = async ( ctx , next ) => { const state = ctx . query . state if ( state != ctx . session . state ) { throw new Error ( 'The state is incorrect.' ) } const redirect_uri = getRedirect ( ctx , path , state ) ctx . session . state = null if ( ctx . query . error ) { const { error : e , error_description } = ctx . query await error ( ctx , e , error_description , next ) return } if ( ! ctx . query . code ) throw new Error ( 'Code Not Found.' ) const token = await exchange ( { client_id , client_secret , code : ctx . query . code , redirect_uri , } ) const data = await getInfo ( token , client_id , client_secret ) await finish ( ctx , token , data , next ) } const redirectMw = session ? [ session , redirect ] : [ redirect ] router . get ( ` ${ path } ` , ... redirectMw ) }
The Mail.Ru OAuth Login Routes For The Idio Web Server.
The Mail . Ru OAuth Login Routes For The Idio Web Server .
/* async */ /* next */