110 lines
4.0 KiB
TypeScript
110 lines
4.0 KiB
TypeScript
import { ZError } from 'common/ZError'
|
|
import BaseController, { ROLE_ANON } from 'common/base.controller'
|
|
import { role, router } from 'decorators/router'
|
|
import logger from 'logger/logger'
|
|
import { AuthRecord } from 'modules/AuthRecord'
|
|
import {
|
|
exchangeTwitterCodeForToken,
|
|
getOAuthAccessTokenWith,
|
|
getOAuthRequestToken,
|
|
getTwitterUserInfo,
|
|
} from 'services/twitter.svr'
|
|
import { parseOauthState } from 'utils/net.util'
|
|
|
|
class TwitterController extends BaseController {
|
|
@role(ROLE_ANON)
|
|
@router('get /twitter/redirect_uri')
|
|
async twitterRedirect(req, res) {
|
|
// logger.info('twitter redirect: ', req.params)
|
|
const { code, state } = req.params
|
|
if (code && state) {
|
|
const stateArr = parseOauthState(state)
|
|
const address = stateArr[0].toLowerCase()
|
|
const record = await AuthRecord.insertOrUpdate(
|
|
{ address, platform: 4 },
|
|
{ address, platform: 4, $inc: { version: 1 } },
|
|
)
|
|
const vcode = stateArr[1] || stateArr[0]
|
|
const tokenResponse = await exchangeTwitterCodeForToken(code, vcode)
|
|
record.accessToken = tokenResponse.access_token
|
|
record.refreshToken = tokenResponse.refresh_token
|
|
record.scope = tokenResponse.scope
|
|
record.tokenType = tokenResponse.token_type
|
|
record.expiresIn = (Date.now() / 1000 + tokenResponse.expires_in || 0) | 0
|
|
await record.save()
|
|
if (tokenResponse && tokenResponse.access_token) {
|
|
const uinfo = await getTwitterUserInfo(tokenResponse.access_token)
|
|
if (!uinfo.data) {
|
|
logger.info('twitter user info: ', JSON.stringify(uinfo))
|
|
}
|
|
record.nickname = uinfo.data?.name
|
|
record.username = uinfo.data?.username
|
|
record.openId = uinfo.data?.id
|
|
if (uinfo.data?.profile_image_url) {
|
|
record.avatar = uinfo.data?.profile_image_url.replace('_normal', '')
|
|
}
|
|
await record.save()
|
|
}
|
|
if (stateArr.length > 2) {
|
|
return res.redirect(stateArr[2])
|
|
}
|
|
}
|
|
if (state) {
|
|
const stateArr = parseOauthState(state)
|
|
if (stateArr.length > 2) {
|
|
return res.redirect(stateArr[2])
|
|
}
|
|
}
|
|
return res.view('/templates/twitter_redirect.ejs')
|
|
}
|
|
|
|
@role(ROLE_ANON)
|
|
@router('get /twitter/oauth/:address')
|
|
async twitterOauth(req, res) {
|
|
let method = 'authenticate'
|
|
let { address } = req.params
|
|
if (!address) {
|
|
throw new ZError(10, 'address needed')
|
|
}
|
|
address = address.toLowerCase()
|
|
// @ts-ignore
|
|
const { oauthRequestToken, oauthRequestTokenSecret } = await getOAuthRequestToken()
|
|
logger.info(
|
|
`twitter request token::oauthRequestToken:${oauthRequestToken},oauthRequestTokenSecret:${oauthRequestTokenSecret}`,
|
|
)
|
|
req.session.oauthRequestToken = oauthRequestToken
|
|
req.session.oauthRequestTokenSecret = oauthRequestTokenSecret
|
|
req.session.address = address
|
|
const authorizationUrl = `https://api.twitter.com/oauth/${method}?oauth_token=${oauthRequestToken}`
|
|
logger.info('redirecting:', authorizationUrl)
|
|
res.redirect(authorizationUrl)
|
|
}
|
|
// for twitter oauth v1.0
|
|
@role(ROLE_ANON)
|
|
@router('get /twitter/callback')
|
|
async twitterOauth1Callback(req, res) {
|
|
const { address, oauthRequestToken, oauthRequestTokenSecret } = req.session
|
|
logger.info('request.query', req.query)
|
|
const { oauth_verifier: oauthVerifier } = req.query
|
|
const { oauthAccessToken, oauthAccessTokenSecret, results } = await getOAuthAccessTokenWith({
|
|
oauthRequestToken,
|
|
oauthRequestTokenSecret,
|
|
oauthVerifier,
|
|
})
|
|
const { user_id: userId /*, screen_name */ } = results
|
|
logger.info('userId:', userId)
|
|
const record = await AuthRecord.insertOrUpdate(
|
|
{ address, platform: 4 },
|
|
{ address, platform: 4, $inc: { version: 1 } },
|
|
)
|
|
record.nickname = results.screen_name
|
|
record.username = results.screen_name
|
|
record.openId = results.user_id
|
|
record.accessToken = oauthAccessToken
|
|
record.refreshToken = oauthAccessTokenSecret
|
|
record.tokenType = 'oauth1'
|
|
await record.save()
|
|
return res.view('/templates/twitter_redirect.ejs')
|
|
}
|
|
}
|