// take access token from url params
const token = ctx.params['accesstoken']
const decoded = Buffer.from(b64uToB64(token), 'base64').toString()
const tokenObj = JSON.parse(decoded)
const signedMessage = tokenObj.signed_message
&& tokenObj.signatures[0]
&& ['login', 'posting', 'offline', 'code', 'refresh']
.includes(signedMessage.type)
// get username from access_token
const username = tokenObj.authors[0]
// initialize Hivesigner with user access_token and app_account from imagehoster config
const cl = new hivesigner.Client({
app: UPLOAD_LIMITS.app_account,
await cl.me(function (err: any, res: any) {
APIError.assert(account, APIError.Code.NoSuchAccount)
ctx.log.warn('uploading app %s', signedMessage.app)
APIError.assert(username === account.name, APIError.Code.InvalidSignature)
// user access_token should have same signed app account as imagehoster defined app account.
APIError.assert(signedMessage.app === UPLOAD_LIMITS.app_account, APIError.Code.InvalidSignature)
APIError.assert(res.scope.includes('comment'), APIError.Code.InvalidSignature)
// check if user has authorized posting authority to app_account
if (account && account.name) {
['posting', 'active', 'owner'].forEach((type) => {
account[type].account_auths.forEach((key: string[]) => {
&& key[0] === UPLOAD_LIMITS.app_account