@@ -33,7 +33,7 @@ import * as fs from 'fs'
3333import * as jwt from 'jsonwebtoken'
3434
3535@Service ( )
36- @Controller ( '/opey' )
36+ @Controller ( '/opey-old ' )
3737/**
3838 * Controller class for handling Opey related operations.
3939 * This used to hold the /chat endpoint, but that endpoint has become obsolete since using websockets.
@@ -45,6 +45,94 @@ export class OpeyController {
4545 private obpClientService : OBPClientService ,
4646 ) { }
4747
48+ @Post ( '/consent' )
49+ /**
50+ * Retrieves a consent from OBP for the current user
51+ */
52+ async getConsent (
53+ @Session ( ) session : any ,
54+ @Req ( ) request : Request ,
55+ @Res ( ) response : Response
56+ ) : Response {
57+ try {
58+ console . log ( "Getting consent from OBP" )
59+ // Check if consent is already in session
60+ if ( session [ 'obpConsent' ] ) {
61+ console . log ( "Consent found in session, returning cached consent ID" )
62+ const obpConsent = session [ 'obpConsent' ]
63+ // NOTE: Arguably we should not return the consent to the frontend as it could be hijacked,
64+ // we can keep everything in the backend and only return the JWT token
65+ return response . status ( 200 ) . json ( { consent_id : obpConsent . consent_id } ) ;
66+ }
67+
68+ const oauthConfig = session [ 'clientConfig' ]
69+ const version = this . obpClientService . getOBPVersion ( )
70+ // Obbiously this should not be hard-coded, especially the consumer_id, but for now it is
71+ const consentRequestBody = {
72+ "everything" : false ,
73+ "views" : [ ] ,
74+ "entitlements" : [ ] ,
75+ "consumer_id" : "33e0a1bd-9f1d-4128-911b-8936110f802f"
76+ }
77+
78+ // Get current user, only proceed if user is logged in
79+ const currentUser = await this . obpClientService . get ( `/obp/${ version } /users/current` , oauthConfig )
80+ const currentResponseKeys = Object . keys ( currentUser )
81+ if ( ! currentResponseKeys . includes ( 'user_id' ) ) {
82+ return response . status ( 400 ) . json ( { message : 'User not logged in, Authentication required' } ) ;
83+ }
84+
85+ // url needs to be changed once we get the 'bankless' consent endpoint
86+ // this creates a consent for the current logged in user, and starts SCA flow i.e. sends SMS or email OTP to user
87+ const consent = await this . obpClientService . create ( `/obp/${ version } /banks/gh.29.uk/my/consents/IMPLICIT` , consentRequestBody , oauthConfig )
88+ console . log ( "Consent: " , consent )
89+
90+ // store consent in session, return consent 200 OK
91+ session [ 'obpConsent' ] = consent
92+ return response . status ( 200 ) . json ( { consent_id : consent . consent_id } ) ;
93+ } catch ( error ) {
94+ console . error ( "Error in consent endpoint: " , error ) ;
95+ return response . status ( 500 ) . json ( { error : 'Internal Server Error ' } ) ;
96+ }
97+ }
98+
99+ @Post ( '/consent/answer-challenge' )
100+ /**
101+ * Endpoint to answer the consent challenge with code i.e. SMS or email OTP for SCA
102+ * If successful, returns a Consent-JWT for use by Opey to access endpoints/ roles that the consenting user has
103+ * This completes (i.e. is the final step in) the consent flow
104+ */
105+ async answerConsentChallenge (
106+ @Session ( ) session : any ,
107+ @Req ( ) request : Request ,
108+ @Res ( ) response : Response
109+ ) : Response {
110+ try {
111+ const oauthConfig = session [ 'clientConfig' ]
112+ const version = this . obpClientService . getOBPVersion ( )
113+
114+ const obpConsent = session [ 'obpConsent' ]
115+ if ( ! obpConsent ) {
116+ return response . status ( 400 ) . json ( { message : 'Consent not found in session' } ) ;
117+ } else if ( obpConsent . status === 'ACCEPTED' ) {
118+ return response . status ( 400 ) . json ( { message : 'Consent already accepted' } ) ;
119+ }
120+ const answerBody = request . body
121+
122+ const consentJWT = await this . obpClientService . create ( `/obp/${ version } /banks/gh.29.uk/consents/${ obpConsent . consent_id } /challenge` , answerBody , oauthConfig )
123+ console . log ( "Consent JWT: " , consentJWT )
124+ // store consent JWT in session, return consent JWT 200 OK
125+ session [ 'obpConsentJWT' ] = consentJWT
126+ return response . status ( 200 ) . json ( true ) ;
127+
128+ } catch ( error ) {
129+ console . error ( "Error in consent/answer-challenge endpoint: " , error ) ;
130+ return response . status ( 500 ) . json ( { error : 'Internal Server Error' } ) ;
131+ }
132+
133+ }
134+
135+
48136 @Post ( '/token' )
49137 /**
50138 * Retrieves a JWT token for the current user.
0 commit comments