import {Config} from "../config.js"
import {AccessLevel, UserClaims} from "../types/types.js"
import {http} from "../utils/http/index.js"
let _userClaims = new Map()
let _apiKey = undefined
let _getIdToken = async () => {
throw new Error("not implemented")
}
/**
* @module auth
*/
/**
* setting Api key
* @param {object} [param0={}]
* @param {Number} [param0.apiKey] - optional variable defining user's API key
* @param {Number} [param0.getIdToken] - optional async function to get user's idToken
*/
export function configure({apiKey, getIdToken}) {
if (apiKey)
_apiKey = apiKey
if (getIdToken)
_getIdToken = getIdToken
_userClaims.clear()
}
/**
* Manually setting userToken
* @param {string} token
* @param {AccessLevel} accessLevel
*/
export function setUserToken(token, accessLevel = AccessLevel.USER) {
if (!token)
return
let c = new UserClaims(token)
if (!c.isExpired())
_userClaims.set(accessLevel, c)
}
/**
*
* @returns {UserClaims}
*/
export async function getUserClaims() {
return getUserToken()
.then(_token => {
return _userClaims.get(AccessLevel.USER)
})
}
/**
*
* @async
* @param {object} [param0={}]
* @param {Number} [param0.minExpiry] - optional variable defining minimum expiry time in seconds
* @param {AccessLevel} [param0.accessLevel=AccessLevel.USER]
* @returns {string} - user Token.
*/
export async function getUserToken({minExpiry, accessLevel} = {}) {
minExpiry = minExpiry || (30 * 60)
accessLevel = accessLevel || AccessLevel.USER
let claim = _userClaims.get(accessLevel)
let refresh = false
let exp = claim ? claim.getSecondsUntilExpiry() : 0
//at least 1 minute expiry time
if (exp < 60) {
claim = undefined
refresh = true
} else if (exp < minExpiry)
refresh = true
if (refresh) {
return _refreshUserToken(accessLevel)
.then(token => {
setUserToken(token, accessLevel)
return token
})
.catch(_err => {
if (claim)
return claim.token
else
throw new Error("unable to create user token")
})
} else {
if (claim)
return claim.token
else
throw new Error("could not create user token")
}
}
/**
* clear user.
*/
export function logout() {
_apiKey = undefined
_userClaims.clear()
}
/**
*
* Generate a new API Key, old API KEY will be discareded
* It require a userToken to be set.
* @returns {string} api key
*/
export async function generateAPIKey() {
let headers = {
"Content-Type": "application/json",
Accept: "application/json",
"x-jibb-user-jwt": await getUserToken(),
}
let response = await http.get(`${Config.apiBaseURL}/v1/auth/apikey`, headers)
return response.data.apiKey
}
/**
*
* Generating a one time password.
* It require a IdToken to be set.
* @async
* @returns {string} - Custom Password.
*/
export async function generateCustomAuthPassword() {
let headers = {
"Content-Type": "application/json",
Accept: "application/json",
"x-jibb-id-jwt": await _getIdToken(),
}
let response = await http.get(`${Config.apiBaseURL}/v1/auth/custom`, headers)
return response.data.password
}
async function _getUserTokenFromApiKey(accessLevel) {
let headers = {
"Content-Type": "application/json",
Accept: "application/json",
}
let body = {
api_key: _apiKey,
}
let url
switch (accessLevel) {
case AccessLevel.ADMIN:
url = `${Config.apiBaseURL}/v1/admin/auth/token`
break
case AccessLevel.SUPERADMIN:
url = `${Config.apiBaseURL}/v1/superadmin/auth/token`
break
default:
url = `${Config.apiBaseURL}/v1/auth/token`
break
}
let response = await http.post(url, body, headers)
return response.data.token
}
async function _getUserTokenFromIDToken(accessLevel) {
let headers = {
"Content-Type": "application/json",
Accept: "application/json",
"x-jibb-id-jwt": await _getIdToken(),
}
let body = {}
let url
switch (accessLevel) {
case AccessLevel.ADMIN:
url = `${Config.apiBaseURL}/v1/admin/auth/token`
break
case AccessLevel.SUPERADMIN:
url = `${Config.apiBaseURL}/v1/superadmin/auth/token`
break
default:
url = `${Config.apiBaseURL}/v1/auth/token`
break
}
let response = await http.post(url, body, headers)
return response.data.token
}
async function _refreshUserToken(accessLevel) {
if (_apiKey) {
return _getUserTokenFromApiKey(accessLevel)
}
return _getUserTokenFromIDToken(accessLevel)
}