1+ import {
2+ IAuthenticateGeneric ,
3+ ICredentialDataDecryptedObject ,
4+ ICredentialTestRequest ,
5+ ICredentialType ,
6+ IHttpRequestHelper ,
7+ IHttpRequestOptions ,
8+ INodeProperties ,
9+ } from 'n8n-workflow' ;
10+
11+ import setCookie from 'set-cookie-parser' ;
12+
13+ export class LowcoderApi implements ICredentialType {
14+ name = 'lowcoderApi' ;
15+ displayName = 'Lowcoder API' ;
16+ properties :INodeProperties [ ] = [
17+ {
18+ displayName :'Cookie Token' ,
19+ name :'sessionToken' ,
20+ type :'hidden' ,
21+
22+ typeOptions :{
23+ expirable :true ,
24+ } ,
25+ default :'' ,
26+ } ,
27+ {
28+ displayName :'API Base URL' ,
29+ name :'url' ,
30+ type :'string' ,
31+ default :'' ,
32+ } ,
33+ {
34+ displayName :'API Token' ,
35+ name :'apiToken' ,
36+ type :'string' ,
37+ default :'' ,
38+ } ,
39+ {
40+ displayName :'Username' ,
41+ name :'username' ,
42+ type :'string' ,
43+ default :'' ,
44+ } ,
45+ {
46+ displayName :'Password' ,
47+ name :'password' ,
48+ type :'string' ,
49+ typeOptions :{
50+ password :true ,
51+ } ,
52+ default :'' ,
53+ } ,
54+ ] ;
55+
56+ // method will only be called if "sessionToken" (the expirable property)
57+ // is empty or is expired
58+ async preAuthentication ( this :IHttpRequestHelper , credentials :ICredentialDataDecryptedObject ) {
59+ // make reques to get session token
60+ const url = credentials . url as string ;
61+ const options = {
62+ method :'POST' ,
63+ url :`${ url . endsWith ( '/' ) ?url . slice ( 0 , - 1 ) :url } /api/auth/form/login` ,
64+ body :{
65+ loginId :credentials . username ,
66+ password :credentials . password ,
67+ register :"false" ,
68+ source :"EMAIL" ,
69+ authId :"EMAIL"
70+ } ,
71+ headers :{
72+ LOWCODER_CE_SELFHOST_TOKEN :credentials . apiToken
73+ } ,
74+ returnFullResponse :true
75+ } as IHttpRequestOptions ;
76+ try {
77+ const request = ( await this . helpers . httpRequest ( options ) ) ;
78+ const tokenCookie = setCookie . parse ( request . headers [ 'set-cookie' ] )
79+ . filter ( cookie => cookie . name === 'LOWCODER_CE_SELFHOST_TOKEN' ) ;
80+ return { sessionToken :tokenCookie [ 0 ] ?. value } ;
81+ } catch ( e :any ) {
82+ var error = new Error ( e . response . data . message ?e . response . data . message :e . error ) ;
83+ error . cause = options as any ;
84+ throw error ;
85+ }
86+ }
87+
88+ authenticate :IAuthenticateGeneric = {
89+ type :'generic' ,
90+ properties :{
91+ headers :{
92+ 'Cookie' :'=LOWCODER_CE_SELFHOST_TOKEN={{$credentials.sessionToken}}' ,
93+ } ,
94+ } ,
95+ } ;
96+
97+ test :ICredentialTestRequest = {
98+ request :{
99+ baseURL :'={{$credentials?.url}}' ,
100+ url :'api/users/me' ,
101+ } ,
102+ } ;
103+ }