Skip to content

Commit aade710

Browse files
authored
feat: new script to verify emails (#436)
1 parent c769631 commit aade710

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

docker/kc-cron-job/utils/bceid-webservice.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,7 @@ async function checkUserExistsAtIDIM({ property = 'userGuid', matchKey = '', env
121121
}
122122

123123
module.exports = {
124+
getWebServiceInfo,
125+
generateXML,
124126
checkUserExistsAtIDIM
125127
};
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
const { promisify } = require('util');
2+
const { parseString } = require('xml2js');
3+
const { getAdminClient } = require('./helpers');
4+
const { generateXML, getWebServiceInfo } = require('./utils/bceid-webservice');
5+
const axios = require('axios');
6+
const parseStringSync = promisify(parseString);
7+
const _ = require('lodash');
8+
//const fs = require('fs');
9+
//const path = require('path');
10+
const async = require('async');
11+
12+
//const basePath = path.join(__dirname, 'exports');
13+
14+
const env = 'prod';
15+
16+
const callSoapService = async (user) => {
17+
const { requestHeaders, requesterIdirGuid, serviceUrl, serviceId } = getWebServiceInfo({ env });
18+
let retries = 3;
19+
while (retries > 0) {
20+
try {
21+
const soapPayload = generateXML({
22+
matchKey: user?.attributes?.idir_username[0],
23+
serviceId,
24+
requesterIdirGuid
25+
});
26+
27+
const response = await axios.post(`${serviceUrl}/webservices/client/V10/BCeIDService.asmx?WSDL`, soapPayload, {
28+
headers: requestHeaders,
29+
timeout: 10000
30+
});
31+
32+
return response;
33+
} catch (error) {
34+
console.error('Error calling SOAP service:', error);
35+
retries--;
36+
if (retries === 0) {
37+
throw error;
38+
}
39+
}
40+
}
41+
};
42+
43+
const verifyKeycloakUsers = async (name, start, callback) => {
44+
const suspeciousUsers = [];
45+
const max = 100;
46+
let first = start;
47+
const adminClient = await getAdminClient(env);
48+
const username = '@idir';
49+
50+
try {
51+
while (true) {
52+
const users = await adminClient.users.find({ realm: 'standard', username, first, max });
53+
if (users.length === 0) break;
54+
55+
for (const user of users) {
56+
console.log('Processing user:', user.username, user.email);
57+
const { attributes } = user;
58+
if (attributes?.idir_username) {
59+
const { data: body } = await callSoapService(user);
60+
61+
const result = await parseStringSync(body);
62+
const data = _.get(
63+
result,
64+
'soap:Envelope.soap:Body.0.searchInternalAccountResponse.0.searchInternalAccountResult.0'
65+
);
66+
67+
if (!data) throw Error('no data');
68+
69+
const status = _.get(data, 'code.0');
70+
71+
if (status === 'Success') {
72+
const email = _.get(data, 'accountList.0.BCeIDAccount.0.contact.0.email.0.value.0');
73+
if (!user.email || !email) {
74+
continue;
75+
}
76+
if (user.email.toLowerCase() !== email.toLowerCase()) {
77+
console.log('Mismatch:', user.username, user.email, email);
78+
suspeciousUsers.push({
79+
username: user.username,
80+
kcEmail: user.email,
81+
bceidEmail: email
82+
});
83+
}
84+
} else {
85+
console.log('Skipping user:', user.username);
86+
console.log('Status:', status);
87+
console.log('Failure Code:', _.get(data, 'failureCode.0'));
88+
continue;
89+
}
90+
}
91+
}
92+
await adminClient.reauth();
93+
first += max;
94+
}
95+
callback(null, { name, start, total: suspeciousUsers.length, suspeciousUsers });
96+
} catch (err) {
97+
console.error('Error:', err);
98+
callback(err);
99+
}
100+
};
101+
102+
async function main() {
103+
async.parallel(
104+
async.reflectAll([
105+
function (cb) {
106+
verifyKeycloakUsers('prod-01', 0, cb);
107+
},
108+
function (cb) {
109+
verifyKeycloakUsers('prod-02', 10000, cb);
110+
},
111+
function (cb) {
112+
verifyKeycloakUsers('prod-03', 20000, cb);
113+
},
114+
function (cb) {
115+
verifyKeycloakUsers('prod-04', 30000, cb);
116+
},
117+
function (cb) {
118+
verifyKeycloakUsers('prod-05', 40000, cb);
119+
}
120+
]),
121+
async function (_, results) {
122+
// if (!fs.existsSync(basePath)) fs.mkdirSync(basePath);
123+
// fs.writeFileSync(
124+
// path.resolve(basePath, `users-${env}-${new Date().getTime()}.json`),
125+
// results.map((r) => JSON.stringify(r)).join('\n\n')
126+
// );
127+
console.log(results.map((r) => JSON.stringify(r)).join('\n\n'));
128+
}
129+
);
130+
}
131+
132+
main();

0 commit comments

Comments
 (0)