diff --git a/modules/apps/migrations/2020-05-29-thirdpartyapps.js b/modules/apps/migrations/2020-05-29-thirdpartyapps.js index 6e3a91484..edf759ba0 100644 --- a/modules/apps/migrations/2020-05-29-thirdpartyapps.js +++ b/modules/apps/migrations/2020-05-29-thirdpartyapps.js @@ -43,6 +43,7 @@ exports.up = async knex => { table.string( 'appId' ).references( 'id' ).inTable( 'server_apps' ).notNullable( ).onDelete( 'cascade' ).index( ) table.string( 'userId' ).references( 'id' ).inTable( 'users' ).notNullable( ).onDelete( 'cascade' ).index( ) table.string( 'tokenId' ).references( 'id' ).inTable( 'api_tokens' ).notNullable( ).onDelete( 'cascade' ).index( ) + table.unique( [ 'appId', 'userId' ] ) } ) diff --git a/modules/apps/services/apps.js b/modules/apps/services/apps.js index 66a3158a7..fd4d57643 100644 --- a/modules/apps/services/apps.js +++ b/modules/apps/services/apps.js @@ -5,8 +5,10 @@ const root = require( 'app-root-path' ) const knex = require( `${root}/db/knex` ) const { createToken, createBareToken } = require( `${root}/modules/core/services/tokens` ) +const ApiTokens = ( ) => knex( 'api_tokens' ) const ServerApps = ( ) => knex( 'server_apps' ) const ServerAppsScopes = ( ) => knex( 'server_apps_scopes' ) +const ServerAppsTokens = ( ) => knex( 'user_server_app_tokens' ) const Scopes = ( ) => knex( 'scopes' ) const AuthorizationCodes = ( ) => knex( 'authorization_codes' ) @@ -72,8 +74,11 @@ module.exports = { const { token: appToken } = await createToken( { userId: code.userId, name: `${app.name}-token`, /* lifespan: 1.21e+9, */ scopes: appScopes } ) + await ServerAppsTokens( ).insert( { userId: code.userId, tokenId: appToken.slice( 0, 10 ), appId: appId } ) + let bareToken = await createBareToken( ) + let refreshToken = { id: bareToken.tokenId, tokenDigest: bareToken.tokenHash, @@ -118,11 +123,16 @@ module.exports = { if ( app.secret !== appSecret ) throw new Error( 'Invalid request' ) - console.log( app ) - // Create the new token const { token: appToken } = await createToken( { userId: userId, name: `${app.name}-token`, /* lifespan: 1.21e+9, */ scopes: app.scopes.map( s => s.name ) } ) + // Delete previous token, if it exists + let previousToken = await ServerAppsTokens( ).select( 'tokenId' ).where( { appId: appId, userId: userId } ).first( ) + if ( previousToken ) + await ApiTokens( ).where( { id: previousToken.tokenId } ).del( ) + + await ServerAppsTokens( ).insert( { userId: userId, tokenId: appToken.slice( 0, 10 ), appId: appId } ) + // Create a new refresh token let bareToken = await createBareToken( ) diff --git a/modules/apps/tests/apps.spec.js b/modules/apps/tests/apps.spec.js index 4c4156521..6a5d8fda2 100644 --- a/modules/apps/tests/apps.spec.js +++ b/modules/apps/tests/apps.spec.js @@ -93,9 +93,12 @@ describe( 'Apps', ( ) => { it( 'Should refresh the token using the refresh token, and get a fresh refresh token and token', async ( ) => { let res = await refreshAppToken( { refreshToken: tokenCreateResponse.refreshToken, appId: myTestApp.id, appSecret: myTestApp.secret, userId: actor.id } ) - console.log( res ) - + expect( res.token ).to.be.a( 'string' ) + expect( res.refreshToken ).to.be.a( 'string' ) + let validation = await validateToken( res.token ) + expect( validation.valid ).to.equal( true ) + expect( validation.userId ).to.equal( actor.id ) } )