Skip to content

Commit

Permalink
feat: anonymous user authentication
Browse files Browse the repository at this point in the history
instead of using a single global api key for apps,
anonymous sessions are used for getting a temporary access
  • Loading branch information
TheGreatRefrigerator committed Sep 10, 2024
1 parent 7c6e65e commit a8f1bfd
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 14 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"@babel/preset-env": "^7.15.8",
"@maphubs/tokml": "^0.6.0",
"@popperjs/core": "^2.4.0",
"appwrite": "^15.0.0",
"autoprefixer": "^7.1.2",
"babel-core": "^7.0.0-bridge.0",
"babel-loader": "^8.1.0",
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 8 additions & 14 deletions src/app-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import I18nBuilder from '@/i18n/i18n-builder'
import constants from '@/resources/constants'
import appConfig from '@/config/app-config'
import AppHooks from '@/support/app-hooks'
import {HttpClient} from 'vue-rest-client'
import utils from '@/support/utils'
import store from '@/store/store'
import router from '@/router'
import lodash from 'lodash'
import Vue from 'vue'
import {getKeyObject} from '@/support/appwrite-utils'

class AppLoader {
constructor() {
Expand Down Expand Up @@ -53,22 +53,16 @@ class AppLoader {
}
this.setInitialSettings(appConfig.orsApiKey, constants.endpoints)
} else {
const httpClient = new HttpClient({baseURL: appConfig.dataServiceBaseUrl})

try {
// Request the public API key from the remote service
// (only works when running the app on valid ORS domains).
const response = await httpClient.http.get(appConfig.publicApiKeyUrl)
this.setInitialSettings(response.data, constants.publicEndpoints)
return response.data
let key_object = await getKeyObject()
this.setInitialSettings(key_object['tyk_api_key'], constants.publicEndpoints)
} catch (error) {
// If the request fails, use the local user key instead
if (ORSKEY && ORSKEY !== 'put-an-ors-key-here' && ORSKEY !== '') {
appConfig.orsApiKey = ORSKEY
}
this.setInitialSettings(appConfig.orsApiKey, constants.endpoints)
console.log('Error acquiring api key:', error)
console.log(error.code)
console.log(error.type)
console.log(error.message)
throw error
}

}
}
}
Expand Down
6 changes: 6 additions & 0 deletions src/config-examples/app-config-example.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ const appConfig = {
defaultLocale: 'en-us', // only set as default a locale that is present in the app. By default, they are: 'en-us', 'de-de' and 'pt-br'
orsApiKey: 'put-here-an-ors-api-key', // ORS API key to be used on the ORS requests. You can get one here: https://openrouteservice.org/dev/#/signup
useUserKey: true, // If the app is using a user ORS API key. // Don't change this unless you know what your doing!
appwrite: { // used for HeiGIT apps
endpoint: '',
projectId: '',
policy: '',
executionId: ''
},
bitlyApiKey: 'put-the-bitly-api-key-here', // Bit.ly key used to generate the short url
bitlyLogin: 'put-the-bitly-login-here', // Bit.ly login used to generate the short url

Expand Down
68 changes: 68 additions & 0 deletions src/support/appwrite-utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// eslint-disable-next-line no-unused-vars
import {Account, Client, Databases, Functions, Models, AppwriteException} from 'appwrite'
import config from '@/config/app-config'

/**
* Returns a Promise including an object with a 'tyk_api_key' property
* @returns {Promise<Models.Document|any|undefined>}
*/
export const getKeyObject = async () => {
const client = new Client()
.setEndpoint(config.appwrite.endpoint) // move to config
.setProject(config.appwrite.projectId) // move to config

const account = new Account(client)
try {
return await getExistingUserSession(account, client)
} catch (error) {
if (error.code === 401 && error.type === 'general_unauthorized_scope') {
console.log('No existing Account')
return await creatNewAnonUser(account, client)
} else {
throw error
}
}
}

/**
* Returns an existing anonymous user session
* @param account
* @param client
* @returns {Promise<Models.Document>}
* @throws AppwriteException
*/
const getExistingUserSession = async (account, client) => {
const currentUser = await account.get()
const databases = new Databases(client)
return await databases.getDocument(
'tyk_integration',
'tyk_anonymous_keys',
currentUser.$id
)
}

/**
* Creates a new anonymous user & session.
* Passes domain & configured policy to specific appwrite function
* @param account
* @param client
* @returns {Promise<any>}
*/
const creatNewAnonUser = async (account, client) => {
try {
await account.createAnonymousSession()
const functions = new Functions(client)

const res = await functions.createExecution(
config.appwrite.executionId,
JSON.stringify({
tag: window.location.origin,
policy: config.appwrite.policy
}),
)
return JSON.parse(res.responseBody)
} catch (error) {
console.error('Error creating anonymous user: ', error)
throw error
}
}

0 comments on commit a8f1bfd

Please sign in to comment.