Consents WIP, add the obp-api-typescript package

This commit is contained in:
Nemo Godebski-Pedersen 2025-03-07 11:14:28 +00:00
parent c8228e171f
commit cde2462612
5 changed files with 74 additions and 35 deletions

9
components.d.ts vendored
View File

@ -9,11 +9,9 @@ declare module 'vue' {
export interface GlobalComponents {
ChatMessage: typeof import('./src/components/ChatMessage.vue')['default']
ChatWidget: typeof import('./src/components/ChatWidget.vue')['default']
ChatWidgetII: typeof import('./src/components/ChatWidgetII.vue')['default']
ChatWidgetOld: typeof import('./src/components/ChatWidgetOld.vue')['default']
Collections: typeof import('./src/components/Collections.vue')['default']
Content: typeof import('./src/components/Content.vue')['default']
ElAffix: typeof import('element-plus/es')['ElAffix']
ElAlert: typeof import('element-plus/es')['ElAlert']
ElAside: typeof import('element-plus/es')['ElAside']
ElBacktop: typeof import('element-plus/es')['ElBacktop']
@ -35,12 +33,8 @@ declare module 'vue' {
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
ElMain: typeof import('element-plus/es')['ElMain']
ElMenu: typeof import('element-plus/es')['ElMenu']
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElRow: typeof import('element-plus/es')['ElRow']
ElScollbar: typeof import('element-plus/es')['ElScollbar']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSrcollbar: typeof import('element-plus/es')['ElSrcollbar']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
GlossarySearchNav: typeof import('./src/components/GlossarySearchNav.vue')['default']
HeaderNav: typeof import('./src/components/HeaderNav.vue')['default']
@ -51,7 +45,4 @@ declare module 'vue' {
RouterView: typeof import('vue-router')['RouterView']
SearchNav: typeof import('./src/components/SearchNav.vue')['default']
}
export interface ComponentCustomProperties {
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
}
}

View File

@ -38,6 +38,7 @@
"markdown-it": "^14.1.0",
"node-fetch": "^2.6.7",
"oauth": "^0.10.0",
"obp-api-typescript": "^1.0.1",
"obp-typescript": "^1.0.36",
"pinia": "^2.0.37",
"prismjs": "^1.29.0",

View File

@ -5,10 +5,9 @@ import { ReadableStream as WebReadableStream } from "stream/web"
import { Service } from 'typedi'
import OBPClientService from '../services/OBPClientService'
import OpeyClientService from '../services/OpeyClientService'
import { LangChainAdapter, streamText } from 'ai';
import { UserInput } from '../schema/OpeySchema'
import { strictEqual } from 'node:assert'
import { APIApi, Configuration, ConsentApi, ConsumerConsentrequestsBody, InlineResponse20151 } from 'obp-api-typescript'
@Service()
@Controller('/opey')
@ -174,37 +173,46 @@ export class OpeyController {
): Promise<Response | any> {
try {
const consentResponse = await fetch(
'https://api.openbankproject.com/obp/v5.1.0/consumer/consent-requests',
let obpToken: string
obpToken = await this.obpClientService.getDirectLoginToken()
console.log("Got token: ", obpToken)
const authHeader = `DirectLogin token="${obpToken}"`
console.log("Auth header: ", authHeader)
const obpConfig: Configuration = {
apiKey: authHeader,
basePath: process.env.VITE_OBP_API_HOST,
}
console.log("OBP Config: ", obpConfig)
const consentAPI = new ConsentApi(obpConfig, process.env.VITE_OBP_API_HOST)
// OBP sdk naming is a bit mad, can be rectified in the future
const consentRequestResponse = await consentAPI.oBPv500CreateConsentRequest({
accountAccess: [],
everything: false,
entitlements: [],
consumerId: process.env.VITE_OBP_CONSUMER_KEY? process.env.VITE_OBP_CONSUMER_KEY : '',
} as unknown as ConsumerConsentrequestsBody,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `DirectLogin token=${session['obpToken']}`
},
body: JSON.stringify({
"consent_request": {
"to": {
"bank_id": "gh.29.uk",
"account_id": "8ca8a7e4-6d02-48e3-a029-0b2bf89de9f0"
},
"permissions": [
{
"read": true,
"write": true
}
]
}
})
}
)
// console.log("Consent request response: ", res)
console.log("Consent request response: ", consentRequestResponse)
console.log({consentId: consentRequestResponse.data.consent_request_id})
return response.status(200).json(JSON.stringify({consentId: consentRequestResponse.data.consent_request_id}))
//console.log(await response.body.json())
// if (!res) {
// throw new Error(`Error getting consent request: ${JSON.stringify(res)}`)
// }
} catch (error) {
console.error("Error in consent/request endpoint: ", error);
return response.status(500).json({ error: 'Internal Server Error' });

View File

@ -56,6 +56,7 @@ export default class OBPClientService {
version: process.env.VITE_OBP_API_VERSION as Version,
oauthConfig: this.oauthConfig
}
}
async get(path: string, clientConfig: any): Promise<any> {
const config = this.getSessionConfig(clientConfig)
@ -84,4 +85,31 @@ export default class OBPClientService {
getOBPClientConfig(): any {
return this.clientConfig
}
async getDirectLoginToken(): Promise<string> {
// Hilariously insecure, should be replaced with an OAuth 2 flow as soon as possible
const consumerKey = this.oauthConfig.consumerKey
const username = process.env.VITE_OBP_DIRECT_LOGIN_USERNAME
const password = process.env.VITE_OBP_DIRECT_LOGIN_PASSWORD
const authHeader = `DirectLogin username="${username}",password="${password}",consumer_key="${consumerKey}"`
// Get token from OBP
const tokenResponse = await fetch(`${this.clientConfig.baseUri}/my/logins/direct`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': authHeader
}
})
if (!tokenResponse.ok) {
throw new Error(`Failed to get direct login token: ${tokenResponse.statusText} ${await tokenResponse.text()}`)
}
const token = await tokenResponse.json()
return token.token
}
}

View File

@ -23,6 +23,7 @@ export default {
thread_id: uuidv4(),
input: '',
lastUserMessasgeFailed: false,
userHasConsented: false,
opeyContext: reactive({
currentAssistantMessage: {
id: '',
@ -38,8 +39,18 @@ export default {
ChatMessage,
},
methods: {
toggleChat() {
async toggleChat() {
this.chatOpen = !this.chatOpen
if (!this.userHasConsented) {
await this.initiateConsentFlow()
}
},
async initiateConsentFlow() {
const consentResponse = await fetch('/api/opey/consent/request', {
method: 'POST',
})
console.log('Consent Response: ', await consentResponse.json())
},
async onSubmit() {
// Add user message to the messages array