1
+ import { Admin } from "@/app"
1
2
import { consentList } from "@/services/hydra"
2
- import axios from "axios "
3
-
4
- import { createUserAndWalletFromPhone , getUserIdByPhone , randomPhone } from "test/helpers "
3
+ import { sleep } from "@/utils "
4
+ import { exec } from "child_process"
5
+ import puppeteer from "puppeteer "
5
6
6
7
let userId : UserId
7
- const phone = randomPhone ( )
8
- // const phone = "+14152991378" as PhoneNumber
9
-
10
- const redirectUri = "http://localhost/callback"
11
- const scope = "offline read write"
12
- const grant_types = [ "authorization_code" , "refresh_token" ]
8
+ const email = "test@galoy.io" as EmailAddress
13
9
14
10
beforeAll ( async ( ) => {
15
- await createUserAndWalletFromPhone ( phone )
16
- userId = await getUserIdByPhone ( phone )
11
+ const account = await Admin . getAccountByUserEmail ( email )
12
+ if ( account instanceof Error ) throw account
13
+
14
+ userId = account . kratosUserId
17
15
} )
18
16
19
- async function createOAuthClient ( ) {
20
- const hydraAdminUrl = "http://localhost:4445/admin/clients"
21
-
22
- try {
23
- const response = await axios . post ( hydraAdminUrl , {
24
- client_name : "integration_test" ,
25
- grant_types,
26
- response_types : [ "code" , "id_token" ] ,
27
- redirect_uris : [ redirectUri ] ,
28
- scope,
29
- skip_consent : true ,
17
+ const getOTP = ( email : string ) : Promise < string > => {
18
+ return new Promise ( ( resolve , reject ) => {
19
+ const query = `docker exec -i galoy-dev-kratos-pg-1 psql -U dbuser -d default -t -c "SELECT body FROM courier_messages WHERE recipient='${ email } ' ORDER BY created_at DESC LIMIT 1;"`
20
+ exec ( query , ( error , stdout , stderr ) => {
21
+ if ( error ) {
22
+ reject ( `error: ${ error . message } ` )
23
+ return
24
+ }
25
+ if ( stderr ) {
26
+ reject ( `stderr: ${ stderr } ` )
27
+ return
28
+ }
29
+ const otpMatch = stdout . match ( / ( \d { 6 } ) / )
30
+ if ( otpMatch && otpMatch [ 1 ] ) {
31
+ resolve ( otpMatch [ 1 ] )
32
+ } else {
33
+ reject ( "OTP not found in the message" )
34
+ }
30
35
} )
36
+ } )
37
+ }
31
38
32
- const clientId = response . data . client_id
33
- const clientSecret = response . data . client_secret
39
+ async function performOAuthLogin ( ) {
40
+ const screenshots = false
34
41
35
- return { clientId, clientSecret }
36
- } catch ( error ) {
37
- console . error ( "Error creating OAuth client:" , error . response )
38
- }
39
- }
42
+ const browser = await puppeteer . launch ( )
43
+ // const browser = await puppeteer.launch({ headless: true })
44
+ const page = await browser . newPage ( )
40
45
41
- async function performOAuthLogin ( {
42
- clientId,
43
- clientSecret,
44
- } : {
45
- clientId : string
46
- clientSecret : string
47
- } ) {
48
- // create oauth2 client
49
-
50
- const responseType = "code"
51
- const randomState = "MKfNw-q60talMJ4GU_h1kHFvcPtnQkZI0XLpTkHvJL4"
52
-
53
- const authUrl = `http://localhost:4444/oauth2/auth?response_type=${ responseType } &client_id=${ clientId } &redirect_uri=${ encodeURIComponent ( redirectUri ) } &scope=${ encodeURIComponent ( scope ) } &state=${ randomState } `
54
-
55
- // https://oauth.blink.sv/oauth2/auth?client_id=73ae7c3e-e526-412a-856c-25d1ae0cbc55&scope=read%20write&response_type=code&redirect_uri=https%3A%2F%2Fdashboard.blink.sv%2Fapi%2Fauth%2Fcallback%2Fblink&state=MKfNw-q60talMJ4GU_h1kHFvcPtnQkZI0XLpTkHvJL4
56
-
57
- // Simulate user going to the authorization URL and logging in
58
- // This part would require a real user interaction or a browser automation tool like puppeteer
59
-
60
- let data
61
- try {
62
- const res = await axios . get ( authUrl )
63
- data = res . data
64
- } catch ( error ) {
65
- console . error ( "Error getting auth URL:" , error )
66
- return
67
- }
68
-
69
- // You need to extract the code from the callback response
70
- const code = data . code // Simplified: Actual extraction depends on your OAuth provider
71
-
72
- console . log ( "data" , data )
73
- console . log ( "code" , code )
74
-
75
- try {
76
- // Exchange the code for a token
77
- const tokenResponse = await axios . post ( "http://localhost:4444/oauth2/token" , {
78
- code,
79
- redirect_uri : redirectUri ,
80
- client_id : clientId ,
81
- client_secret : clientSecret ,
82
- grant_type : "authorization_code" ,
83
- } )
46
+ // Navigate the page to a URL
47
+ await page . goto ( "http://localhost:3001/api/auth/signin" )
48
+
49
+ screenshots && ( await page . screenshot ( { path : "screenshot0.png" } ) )
84
50
85
- const accessToken = tokenResponse . data . access_token
51
+ await page . waitForSelector ( ".button" )
52
+ await page . click ( ".button" )
86
53
87
- // Use the access token to get user info or other secured resources
88
- // Update the consent list as needed
89
- return accessToken // This might be used for further secured requests
90
- } catch ( error ) {
91
- console . error ( "Error exchanging code for token:" , error )
92
- }
54
+ screenshots && ( await page . screenshot ( { path : "screenshot1.png" } ) )
55
+
56
+ await page . waitForSelector ( '[data-testid="email_id_input"]' )
57
+ await page . waitForFunction (
58
+ "document.querySelector(\"[data-testid='email_id_input']\").isConnected" ,
59
+ )
60
+ await page . type ( '[data-testid="email_id_input"]' , email )
61
+ screenshots && ( await page . screenshot ( { path : "screenshot2.png" } ) )
62
+ await sleep ( 250 )
63
+
64
+ await page . click ( "#accept" )
65
+
66
+ await sleep ( 500 )
67
+ screenshots && ( await page . screenshot ( { path : "screenshot3.png" } ) )
68
+
69
+ const otp = await getOTP ( email )
70
+
71
+ await page . waitForSelector ( "#code" )
72
+ await page . type ( "#code" , otp , { delay : 100 } )
73
+
74
+ screenshots && ( await page . screenshot ( { path : "screenshot4.png" } ) )
75
+ await sleep ( 1500 )
76
+ screenshots && ( await page . screenshot ( { path : "screenshot5.png" } ) )
77
+
78
+ await page . close ( )
79
+ await browser . close ( )
93
80
}
94
81
95
82
describe ( "Hydra" , ( ) => {
@@ -99,12 +86,16 @@ describe("Hydra", () => {
99
86
} )
100
87
101
88
it ( "get consent list when the user had perform oauth2 login" , async ( ) => {
102
- const res = await createOAuthClient ( )
103
- if ( ! res ) return
104
- const { clientId, clientSecret } = res
105
- console . log ( "clientId" , clientId , "clientSecret" , clientSecret )
89
+ await performOAuthLogin ( )
106
90
107
- const accessToken = await performOAuthLogin ( { clientId, clientSecret } )
108
- console . log ( "accessToken" , accessToken )
91
+ const res = await consentList ( userId )
92
+ expect ( res ) . toEqual ( [
93
+ {
94
+ app : "dashboard" ,
95
+ handledAt : expect . any ( Date ) ,
96
+ remember : false ,
97
+ scope : [ "read" , "write" ] ,
98
+ } ,
99
+ ] )
109
100
} )
110
101
} )
0 commit comments