n8n-nodes-amis-v1 0.1.5 → 0.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -99,19 +99,7 @@ class MisaAmisLogin {
|
|
|
99
99
|
},
|
|
100
100
|
},
|
|
101
101
|
},
|
|
102
|
-
|
|
103
|
-
displayName: 'Request ID',
|
|
104
|
-
name: 'requestId',
|
|
105
|
-
type: 'string',
|
|
106
|
-
default: '',
|
|
107
|
-
required: true,
|
|
108
|
-
displayOptions: {
|
|
109
|
-
show: {
|
|
110
|
-
operation: ['checkLogin'],
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
description: 'The CDRequestId returned from "Generate QR" step',
|
|
114
|
-
},
|
|
102
|
+
// Removed requestId and cookieJar inputs because we use file-based state
|
|
115
103
|
],
|
|
116
104
|
};
|
|
117
105
|
}
|
|
@@ -125,6 +113,9 @@ class MisaAmisLogin {
|
|
|
125
113
|
if (!fs.existsSync(storagePath)) {
|
|
126
114
|
fs.mkdirSync(storagePath, { recursive: true });
|
|
127
115
|
}
|
|
116
|
+
// File paths
|
|
117
|
+
const sessionFilePath = path.join(storagePath, `${userIdentity}.json`);
|
|
118
|
+
const pendingFilePath = path.join(storagePath, `${userIdentity}.pending.json`);
|
|
128
119
|
const clientId = '6bcbc4d1-5426-42f7-bc61-69cac2e229f4';
|
|
129
120
|
const headers = {
|
|
130
121
|
'Content-Type': 'application/json',
|
|
@@ -155,11 +146,19 @@ class MisaAmisLogin {
|
|
|
155
146
|
const cdRequestId = genQrRes.data.CDRequestId;
|
|
156
147
|
const qrContent = `https://amisapp.misa.vn/shared?app=qrlogin&qrid=${cdRequestId}&domain=amisapp.misa.vn`;
|
|
157
148
|
const qrBuffer = await qrcode_1.default.toBuffer(qrContent);
|
|
149
|
+
// SAVE PENDING STATE
|
|
150
|
+
const serializedJar = await jar.serialize();
|
|
151
|
+
const pendingState = {
|
|
152
|
+
requestId: cdRequestId,
|
|
153
|
+
cookieJar: serializedJar,
|
|
154
|
+
timestamp: Date.now()
|
|
155
|
+
};
|
|
156
|
+
fs.writeFileSync(pendingFilePath, JSON.stringify(pendingState, null, 2));
|
|
158
157
|
returnData.push({
|
|
159
158
|
json: {
|
|
160
|
-
message: "QR Generated. Scan
|
|
159
|
+
message: "QR Generated. Please Scan. Pending session saved.",
|
|
160
|
+
userIdentity: userIdentity,
|
|
161
161
|
requestId: cdRequestId,
|
|
162
|
-
clientId: clientId,
|
|
163
162
|
qrContent: qrContent
|
|
164
163
|
},
|
|
165
164
|
binary: {
|
|
@@ -173,16 +172,29 @@ class MisaAmisLogin {
|
|
|
173
172
|
}
|
|
174
173
|
else if (operation === 'checkLogin') {
|
|
175
174
|
// --- Operation: Check Login ---
|
|
176
|
-
|
|
177
|
-
|
|
175
|
+
// READ PENDING STATE
|
|
176
|
+
if (!fs.existsSync(pendingFilePath)) {
|
|
177
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `No pending login found for user '${userIdentity}'. Please run 'Generate QR' first.`);
|
|
178
|
+
}
|
|
179
|
+
const pendingState = JSON.parse(fs.readFileSync(pendingFilePath, 'utf8'));
|
|
180
|
+
const cdRequestId = pendingState.requestId;
|
|
181
|
+
// Restore Cookies
|
|
182
|
+
if (pendingState.cookieJar) {
|
|
183
|
+
const deserialized = await tough_cookie_1.CookieJar.deserialize(pendingState.cookieJar);
|
|
184
|
+
await jar.removeAllCookies();
|
|
185
|
+
for (const cookie of await deserialized.getCookies('https://id.misa.vn')) {
|
|
186
|
+
await jar.setCookie(cookie, 'https://id.misa.vn');
|
|
187
|
+
}
|
|
188
|
+
}
|
|
178
189
|
let pollingSuccess = false;
|
|
179
190
|
let attempts = 0;
|
|
180
|
-
const maxAttempts = 60; // 2 minutes
|
|
191
|
+
const maxAttempts = 60; // 2 minutes
|
|
181
192
|
while (!pollingSuccess && attempts < maxAttempts) {
|
|
182
193
|
attempts++;
|
|
183
194
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
184
195
|
try {
|
|
185
196
|
const pollUrl = `https://id.misa.vn/api/login-cross-device/v2/polling?cdRequestId=${cdRequestId}&clientId=${clientId}&deviceId=${clientId}`;
|
|
197
|
+
console.log(`[MISA Debug] Polling Attempt ${attempts}: ${pollUrl}`);
|
|
186
198
|
const pollRes = await client.get(pollUrl, { headers });
|
|
187
199
|
if (JSON.stringify(pollRes.data).includes("Success") || JSON.stringify(pollRes.data).includes("v1/auth/token")) {
|
|
188
200
|
pollingSuccess = true;
|
|
@@ -190,15 +202,19 @@ class MisaAmisLogin {
|
|
|
190
202
|
}
|
|
191
203
|
catch (error) {
|
|
192
204
|
if (error.response && error.response.status >= 400 && error.response.status < 500) {
|
|
193
|
-
|
|
194
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Polling Error ${error.response.status}: ${JSON.stringify(error.response.data)}. Please Generate QR again.`);
|
|
205
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Polling Error: ${JSON.stringify(error.response.data)}. Please Generate QR again.`);
|
|
195
206
|
}
|
|
196
|
-
// Ignore server errors or network glitches (retry)
|
|
197
207
|
}
|
|
198
208
|
}
|
|
199
209
|
if (pollingSuccess) {
|
|
210
|
+
// Save FINAL Session
|
|
200
211
|
const serializedJar = await jar.serialize();
|
|
201
212
|
fs.writeFileSync(sessionFilePath, JSON.stringify(serializedJar, null, 2));
|
|
213
|
+
// Cleanup Pending
|
|
214
|
+
try {
|
|
215
|
+
fs.unlinkSync(pendingFilePath);
|
|
216
|
+
}
|
|
217
|
+
catch (e) { }
|
|
202
218
|
returnData.push({
|
|
203
219
|
json: {
|
|
204
220
|
message: "Login Successful",
|
|
@@ -208,7 +224,7 @@ class MisaAmisLogin {
|
|
|
208
224
|
});
|
|
209
225
|
}
|
|
210
226
|
else {
|
|
211
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Login timeout
|
|
227
|
+
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Login timeout. Please scan QR Code again.');
|
|
212
228
|
}
|
|
213
229
|
}
|
|
214
230
|
}
|