'use strict' ; import { Config } from '@Base/config' ; import { AuthToken } from '@Entities/AuthToken' ; import { createObject , getObject , getObjects , updateObjectFields , deleteMany , deleteOne } from '@Tools/Db' ; import { GenericFilter } from '@Entities/EntityFilters/GenericFilter' ; import { CriteriaFilter } from '@Entities/EntityFilters/CriteriaFilter' ; import { SArray , VKeyedCollection } from '@Tools/vTypes' ; import { Clamp , GenUUID , IsNullOrEmpty , IsNotNullOrEmpty } from '@Tools/Misc' ; import { Logger } from '@Tools/Logging' ; export let tokenCollection = 'tokens' ; export function initTokens ( ) { setInterval ( async ( ) => { const nowtime = new Date ( ) ; const deletedTokens = await deleteMany ( tokenCollection , new GenericFilter ( { 'expirationTime' : { $lt : nowtime } } ) ) ; if ( deletedTokens > 0 ) { Logger . debug ( `Tokens.Expiration: expired ${ deletedTokens } tokens` ) ; } ; } , 1000 * 60 * 5 ) ; } ; export class TokenScope { public static OWNER : string = 'owner' ; public static DOMAIN : string = 'domain' ; public static PLACE : string = 'place' ; public static READ : string = 'read' ; public static WRITE : string = 'write' ; static KnownScope ( pScope ) { return [ TokenScope . OWNER , TokenScope . DOMAIN , TokenScope . PLACE ] . includes ( pScope ) ; } ; } ; export const Tokens = { async createToken ( pAccountId , pScope , pExpireHours = 0 ) { const aToken = new AuthToken ( ) ; aToken . id = GenUUID ( ) ; aToken . token = GenUUID ( ) ; aToken . refreshToken = GenUUID ( ) ; aToken . accountId = pAccountId ; aToken . scope = [ ] ; pScope . forEach ( aScope => { if ( TokenScope . KnownScope ( aScope ) ) aToken . scope . push ( aScope ) ; } ) ; aToken . whenCreated = new Date ( ) ; switch ( pExpireHours ) { case 0 : aToken . expirationTime = Tokens . computeDefaultExpiration ( aToken . scope , aToken . whenCreated ) ; break ; case - 1 : aToken . expirationTime = new Date ( 2399 , 12 ) ; break ; default : const hours = Clamp ( pExpireHours , 1 , 1000000 ) ; aToken . expirationTime = new Date ( new Date ( ) . valueOf ( ) + hours * 1000 * 60 * 60 ) ; break ; } ; return aToken ; } , async getTokenWithTokenId ( pTokenId ) { return IsNullOrEmpty ( pTokenId ) ? null : getObject ( tokenCollection , new GenericFilter ( { 'id' : pTokenId } ) ) ; } , async getTokenWithToken ( pToken ) { return IsNullOrEmpty ( pToken ) ? null : getObject ( tokenCollection , new GenericFilter ( { 'token' : pToken } ) ) ; } , async getTokenWithRefreshToken ( pToken ) { return IsNullOrEmpty ( pToken ) ? null : getObject ( tokenCollection , new GenericFilter ( { 'refreshToken' : pToken } ) ) ; } , async addToken ( pAuthToken ) { return createObject ( tokenCollection , pAuthToken ) ; } , async removeToken ( pAuthToken ) { return deleteOne ( tokenCollection , new GenericFilter ( { 'id' : pAuthToken . id } ) ) ; } , async updateTokenFields ( pEntity , pFields ) { return updateObjectFields ( tokenCollection , new GenericFilter ( { 'id' : pEntity . id } ) , pFields ) ; } , async * getTokensForOwner ( pOwnerId , pPager ? ) { return IsNullOrEmpty ( pOwnerId ) ? null : Tokens . enumerateAsync ( new GenericFilter ( { 'accountId' : pOwnerId } ) , pPager ) ; } , async * enumerateAsync ( pFilter ? , pPager ? , pScoper ? ) { for await ( const tok of getObjects ( tokenCollection , pFilter , pPager , pScoper ) ) { yield tok ; } ; } , computeDefaultExpiration ( pScopes , pBaseDate ? ) { return new Date ( ( pBaseDate ? pBaseDate . valueOf ( ) : new Date ( ) . valueOf ( ) ) + ( SArray . has ( pScopes , TokenScope . DOMAIN ) ? Config . auth [ "domain-token-expire-hours" ] * 1000 * 60 * 60 : Config . auth [ "owner-token-expire-hours" ] * 1000 * 60 * 60 ) ) ; } , hasNotExpired ( pAuthToken ) { return IsNullOrEmpty ( pAuthToken ) ? false : pAuthToken . expirationTime . valueOf ( ) > new Date ( ) . valueOf ( ) ; } , createSpecialAdminToken ( ) { const aToken = new AuthToken ( ) ; aToken . id = GenUUID ( ) ; aToken . token = specialAdminTokenToken ; aToken . refreshToken = GenUUID ( ) ; aToken . accountId = GenUUID ( ) ; aToken . scope = [ TokenScope . OWNER ] ; aToken . whenCreated = new Date ( ) ; aToken . expirationTime = new Date ( new Date ( ) . valueOf ( ) + 1000 ) ; return aToken ; } , isSpecialAdminToken ( pAuthToken ) { return pAuthToken . token === specialAdminTokenToken && Tokens . hasNotExpired ( pAuthToken ) ; } } ; const specialAdminTokenToken = GenUUID ( ) ;