Skip to content

Commit dc2753a

Browse files
committed
fix: more flexible user matching
1 parent ae424c1 commit dc2753a

7 files changed

Lines changed: 288 additions & 97 deletions

File tree

dist/index.js

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81717,23 +81717,61 @@ var SlackAppUrl;
8171781717
;// CONCATENATED MODULE: ./src/utils/slack/user-matchers.ts
8171881718

8171981719

81720+
/**
81721+
* Redacts sensitive information for safe logging
81722+
* Replaces characters with * but keeps first and last character
81723+
* For emails, preserves the domain part
81724+
*/
81725+
function redact(text) {
81726+
if (!text) {
81727+
return '';
81728+
}
81729+
// Handle email addresses specially
81730+
if (text.includes('@')) {
81731+
const [localPart, domainPart] = text.split('@');
81732+
if (localPart.length <= 2) {
81733+
return `${localPart}@${domainPart}`;
81734+
}
81735+
return `${localPart[0]}${'*'.repeat(localPart.length - 2)}${localPart[localPart.length - 1]}@${domainPart}`;
81736+
}
81737+
// Handle regular text
81738+
if (text.length <= 2) {
81739+
return text;
81740+
}
81741+
return `${text[0]}${'*'.repeat(text.length - 2)}${text[text.length - 1]}`;
81742+
}
8172081743
function customMappingMatcher(githubUsername, slackUsername) {
8172181744
return {
81722-
check: (user) => user.name?.toLowerCase() === slackUsername.toLowerCase() ||
81723-
user.profile?.display_name?.toLowerCase() === slackUsername.toLowerCase() ||
81724-
user.profile?.real_name?.toLowerCase() === slackUsername.toLowerCase(),
81745+
check: (user) => {
81746+
const name = user.name?.toLowerCase() ?? '';
81747+
const displayName = user.profile?.display_name?.toLowerCase() ?? '';
81748+
const realName = user.profile?.real_name?.toLowerCase() ?? '';
81749+
const slackNameLower = slackUsername.toLowerCase();
81750+
return (name.includes(slackNameLower) ||
81751+
slackNameLower.includes(name) ||
81752+
displayName.includes(slackNameLower) ||
81753+
slackNameLower.includes(displayName) ||
81754+
realName.includes(slackNameLower) ||
81755+
slackNameLower.includes(realName));
81756+
},
8172581757
description: 'custom user mapping',
8172681758
log: (user) => {
8172781759
(0,core.debug)(`Match found by custom mapping: GitHub username [${githubUsername}] to Slack username [${slackUsername}] for user [${user.id}]`);
81760+
(0,core.debug)(`Redacted debug info: GitHub username [${redact(githubUsername)}] to Slack username [${redact(slackUsername)}] matched with user name [${redact(user.name ?? '')}], display_name [${redact(user.profile?.display_name ?? '')}], real_name [${redact(user.profile?.real_name ?? '')}]`);
8172881761
},
8172981762
};
8173081763
}
8173181764
function displayNameMatcher(username) {
8173281765
return {
81733-
check: (user) => user.profile?.display_name?.toLowerCase() === username.toLowerCase(),
81766+
check: (user) => {
81767+
const displayName = user.profile?.display_name?.toLowerCase() ?? '';
81768+
const usernameLower = username.toLowerCase();
81769+
return displayName.includes(usernameLower) || usernameLower.includes(displayName);
81770+
},
8173481771
description: 'user.profile.display_name fields',
8173581772
log: (user) => {
8173681773
(0,core.debug)(`Match found by username [${username}] matching Slack displayName [${user.profile?.display_name}]`);
81774+
(0,core.debug)(`Redacted debug info: username [${redact(username)}] matched with display_name [${redact(user.profile?.display_name ?? '')}]`);
8173781775
},
8173881776
};
8173981777
}
@@ -81745,6 +81783,7 @@ function emailContainsMatcher(username) {
8174581783
description: 'user.profile.email contains check',
8174681784
log: (user) => {
8174781785
(0,core.debug)(`Match found by username [${username}] contained in Slack email [${user.profile?.email}]`);
81786+
(0,core.debug)(`Redacted debug info: username [${redact(username)}] matched with email [${redact(user.profile?.email ?? '')}]`);
8174881787
},
8174981788
};
8175081789
}
@@ -81754,15 +81793,21 @@ function emailMatcher(email) {
8175481793
description: 'user.profile.email fields',
8175581794
log: (user) => {
8175681795
(0,core.debug)(`Match found by email [${email}] with Slack email [${user.profile?.email}]`);
81796+
(0,core.debug)(`Redacted debug info: email [${redact(email)}] matched with Slack email [${redact(user.profile?.email ?? '')}]`);
8175781797
},
8175881798
};
8175981799
}
8176081800
function realNameMatcher(username) {
8176181801
return {
81762-
check: (user) => user.profile?.real_name?.toLowerCase() === username.toLowerCase(),
81802+
check: (user) => {
81803+
const realName = user.profile?.real_name?.toLowerCase() ?? '';
81804+
const usernameLower = username.toLowerCase();
81805+
return realName.includes(usernameLower) || usernameLower.includes(realName);
81806+
},
8176381807
description: 'user.profile.real_name fields',
8176481808
log: (user) => {
8176581809
(0,core.debug)(`Match found by username [${username}] matching Slack realName [${user.profile?.real_name}]`);
81810+
(0,core.debug)(`Redacted debug info: username [${redact(username)}] matched with real_name [${redact(user.profile?.real_name ?? '')}]`);
8176681811
},
8176781812
};
8176881813
}
@@ -81772,6 +81817,7 @@ function userIdMatcher(userId) {
8177281817
description: 'user.id fields',
8177381818
log: (user) => {
8177481819
(0,core.debug)(`Match found by userId [${userId}] with Slack userId [${user.id}]`);
81820+
(0,core.debug)(`Redacted debug info: userId matched with Slack userId [${redact(user.id ?? '')}]`);
8177581821
},
8177681822
};
8177781823
}
@@ -81782,6 +81828,7 @@ const createUserMatchers = ({ email, userId, userMappings = [], username }) => {
8178281828
const matchingMappings = userMappings.filter((mapping) => mapping.githubUsername === username);
8178381829
if (matchingMappings.length > 0) {
8178481830
(0,core.debug)(`Found [${matchingMappings.length}] custom mappings for GitHub username [${username}]`);
81831+
(0,core.debug)(`Redacted debug info: Found [${matchingMappings.length}] custom mappings for GitHub username [${redact(username)}]`);
8178581832
// Add a matcher for each mapping
8178681833
matchingMappings.forEach((mapping) => {
8178781834
matchers.push(customMappingMatcher(username, mapping.slackUsername));
@@ -81804,25 +81851,35 @@ const createUserMatchers = ({ email, userId, userMappings = [], username }) => {
8180481851
};
8180581852
const logFailedMatches = ({ email, userId, userMappings = [], username }, usersCount) => {
8180681853
console.log(`No user match found for [${username}] after checking against [${usersCount}] Slack ${(0,src.plural)('user', usersCount)}`);
81854+
// Redacted version
81855+
console.log(`Redacted debug info: No user match found for [${redact(username ?? '')}] after checking against [${usersCount}] Slack ${(0,src.plural)('user', usersCount)}`);
8180781856
// Log mapping failures
8180881857
if (username && userMappings.length > 0) {
8180981858
const matchingMappings = userMappings.filter((mapping) => mapping.githubUsername === username);
8181081859
if (matchingMappings.length > 0) {
8181181860
(0,core.debug)(`WARNING: Custom mappings for GitHub username [${username}] were defined but no matching Slack users were found:`);
81861+
(0,core.debug)(`Redacted debug info: WARNING: Custom mappings for GitHub username [${redact(username)}] were defined but no matching Slack users were found:`);
8181281862
// Show each mapping that failed
8181381863
matchingMappings.forEach((mapping) => {
8181481864
(0,core.debug)(` - Mapped to Slack username [${mapping.slackUsername}] but no Slack user with this name/display_name/real_name was found`);
81865+
(0,core.debug)(` - Redacted debug info: Mapped to Slack username [${redact(mapping.slackUsername)}] but no Slack user with this name/display_name/real_name was found`);
8181581866
});
8181681867
(0,core.debug)(`Attempted to fall back to standard matching methods`);
8181781868
}
8181881869
}
8181981870
// Log standard matchers that were tried
81820-
if (userId)
81871+
if (userId) {
8182181872
(0,core.debug)(`Tried to match userId [${userId}] against Slack user.id fields`);
81822-
if (email)
81873+
(0,core.debug)(`Redacted debug info: Tried to match userId [${redact(userId)}] against Slack user.id fields`);
81874+
}
81875+
if (email) {
8182381876
(0,core.debug)(`Tried to match email [${email}] against Slack user.profile.email fields`);
81824-
if (username)
81877+
(0,core.debug)(`Redacted debug info: Tried to match email [${redact(email)}] against Slack user.profile.email fields`);
81878+
}
81879+
if (username) {
8182581880
(0,core.debug)(`Tried to match username [${username}] against Slack user.profile.email (contains), display_name and real_name fields`);
81881+
(0,core.debug)(`Redacted debug info: Tried to match username [${redact(username)}] against Slack user.profile.email (contains), display_name and real_name fields`);
81882+
}
8182681883
(0,core.debug)(`Since no Slack user match found, unable to @mention user or use their profile image`);
8182781884
};
8182881885

@@ -90631,7 +90688,7 @@ module.exports = {"version":"3.17.0"};
9063190688
/***/ 8330:
9063290689
/***/ ((module) => {
9063390690

90634-
module.exports = /*#__PURE__*/JSON.parse('{"UU":"@krauters/github-notifier","rE":"1.3.2","TB":"https://buymeacoffee.com/coltenkrauter"}');
90691+
module.exports = /*#__PURE__*/JSON.parse('{"UU":"@krauters/github-notifier","rE":"1.3.3","TB":"https://buymeacoffee.com/coltenkrauter"}');
9063590692

9063690693
/***/ })
9063790694

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@krauters/github-notifier",
33
"description": "GitHub Notifier by Krauters – Post Open Pull Requests to Slack",
4-
"version": "1.3.2",
4+
"version": "1.3.3",
55
"author": "Colten Krauter <coltenkrauter>",
66
"type": "module",
77
"homepage": "https://buymeacoffee.com/coltenkrauter",

src/utils/slack/user-matchers.ts

Lines changed: 101 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,77 @@ export interface UserMatcher {
1717
log: (user: Member) => void
1818
}
1919

20+
/**
21+
* Redacts sensitive information for safe logging
22+
* Replaces characters with * but keeps first and last character
23+
* For emails, preserves the domain part
24+
*/
25+
export function redact(text: string): string {
26+
if (!text) {
27+
return ''
28+
}
29+
30+
// Handle email addresses specially
31+
if (text.includes('@')) {
32+
const [localPart, domainPart] = text.split('@')
33+
if (localPart.length <= 2) {
34+
return `${localPart}@${domainPart}`
35+
}
36+
37+
return `${localPart[0]}${'*'.repeat(localPart.length - 2)}${localPart[localPart.length - 1]}@${domainPart}`
38+
}
39+
40+
// Handle regular text
41+
if (text.length <= 2) {
42+
return text
43+
}
44+
45+
return `${text[0]}${'*'.repeat(text.length - 2)}${text[text.length - 1]}`
46+
}
47+
2048
function customMappingMatcher(githubUsername: string, slackUsername: string): UserMatcher {
2149
return {
22-
check: (user: Member) =>
23-
user.name?.toLowerCase() === slackUsername.toLowerCase() ||
24-
user.profile?.display_name?.toLowerCase() === slackUsername.toLowerCase() ||
25-
user.profile?.real_name?.toLowerCase() === slackUsername.toLowerCase(),
50+
check: (user: Member) => {
51+
const name = user.name?.toLowerCase() ?? ''
52+
const displayName = user.profile?.display_name?.toLowerCase() ?? ''
53+
const realName = user.profile?.real_name?.toLowerCase() ?? ''
54+
const slackNameLower = slackUsername.toLowerCase()
55+
56+
return (
57+
name.includes(slackNameLower) ||
58+
slackNameLower.includes(name) ||
59+
displayName.includes(slackNameLower) ||
60+
slackNameLower.includes(displayName) ||
61+
realName.includes(slackNameLower) ||
62+
slackNameLower.includes(realName)
63+
)
64+
},
2665
description: 'custom user mapping',
2766
log: (user: Member) => {
2867
debug(
2968
`Match found by custom mapping: GitHub username [${githubUsername}] to Slack username [${slackUsername}] for user [${user.id}]`,
3069
)
70+
debug(
71+
`Redacted debug info: GitHub username [${redact(githubUsername)}] to Slack username [${redact(slackUsername)}] matched with user name [${redact(user.name ?? '')}], display_name [${redact(user.profile?.display_name ?? '')}], real_name [${redact(user.profile?.real_name ?? '')}]`,
72+
)
3173
},
3274
}
3375
}
3476

3577
function displayNameMatcher(username: string): UserMatcher {
3678
return {
37-
check: (user: Member) => user.profile?.display_name?.toLowerCase() === username.toLowerCase(),
79+
check: (user: Member) => {
80+
const displayName = user.profile?.display_name?.toLowerCase() ?? ''
81+
const usernameLower = username.toLowerCase()
82+
83+
return displayName.includes(usernameLower) || usernameLower.includes(displayName)
84+
},
3885
description: 'user.profile.display_name fields',
3986
log: (user: Member) => {
4087
debug(`Match found by username [${username}] matching Slack displayName [${user.profile?.display_name}]`)
88+
debug(
89+
`Redacted debug info: username [${redact(username)}] matched with display_name [${redact(user.profile?.display_name ?? '')}]`,
90+
)
4191
},
4292
}
4393
}
@@ -51,6 +101,9 @@ function emailContainsMatcher(username: string): UserMatcher {
51101
description: 'user.profile.email contains check',
52102
log: (user: Member) => {
53103
debug(`Match found by username [${username}] contained in Slack email [${user.profile?.email}]`)
104+
debug(
105+
`Redacted debug info: username [${redact(username)}] matched with email [${redact(user.profile?.email ?? '')}]`,
106+
)
54107
},
55108
}
56109
}
@@ -61,16 +114,27 @@ function emailMatcher(email: string): UserMatcher {
61114
description: 'user.profile.email fields',
62115
log: (user: Member) => {
63116
debug(`Match found by email [${email}] with Slack email [${user.profile?.email}]`)
117+
debug(
118+
`Redacted debug info: email [${redact(email)}] matched with Slack email [${redact(user.profile?.email ?? '')}]`,
119+
)
64120
},
65121
}
66122
}
67123

68124
function realNameMatcher(username: string): UserMatcher {
69125
return {
70-
check: (user: Member) => user.profile?.real_name?.toLowerCase() === username.toLowerCase(),
126+
check: (user: Member) => {
127+
const realName = user.profile?.real_name?.toLowerCase() ?? ''
128+
const usernameLower = username.toLowerCase()
129+
130+
return realName.includes(usernameLower) || usernameLower.includes(realName)
131+
},
71132
description: 'user.profile.real_name fields',
72133
log: (user: Member) => {
73134
debug(`Match found by username [${username}] matching Slack realName [${user.profile?.real_name}]`)
135+
debug(
136+
`Redacted debug info: username [${redact(username)}] matched with real_name [${redact(user.profile?.real_name ?? '')}]`,
137+
)
74138
},
75139
}
76140
}
@@ -81,6 +145,7 @@ function userIdMatcher(userId: string): UserMatcher {
81145
description: 'user.id fields',
82146
log: (user: Member) => {
83147
debug(`Match found by userId [${userId}] with Slack userId [${user.id}]`)
148+
debug(`Redacted debug info: userId matched with Slack userId [${redact(user.id ?? '')}]`)
84149
},
85150
}
86151
}
@@ -94,6 +159,9 @@ export const createUserMatchers = ({ email, userId, userMappings = [], username
94159

95160
if (matchingMappings.length > 0) {
96161
debug(`Found [${matchingMappings.length}] custom mappings for GitHub username [${username}]`)
162+
debug(
163+
`Redacted debug info: Found [${matchingMappings.length}] custom mappings for GitHub username [${redact(username)}]`,
164+
)
97165

98166
// Add a matcher for each mapping
99167
matchingMappings.forEach((mapping) => {
@@ -128,6 +196,11 @@ export const logFailedMatches = (
128196
`No user match found for [${username}] after checking against [${usersCount}] Slack ${plural('user', usersCount)}`,
129197
)
130198

199+
// Redacted version
200+
console.log(
201+
`Redacted debug info: No user match found for [${redact(username ?? '')}] after checking against [${usersCount}] Slack ${plural('user', usersCount)}`,
202+
)
203+
131204
// Log mapping failures
132205
if (username && userMappings.length > 0) {
133206
const matchingMappings = userMappings.filter((mapping) => mapping.githubUsername === username)
@@ -136,24 +209,43 @@ export const logFailedMatches = (
136209
`WARNING: Custom mappings for GitHub username [${username}] were defined but no matching Slack users were found:`,
137210
)
138211

212+
debug(
213+
`Redacted debug info: WARNING: Custom mappings for GitHub username [${redact(username)}] were defined but no matching Slack users were found:`,
214+
)
215+
139216
// Show each mapping that failed
140217
matchingMappings.forEach((mapping) => {
141218
debug(
142219
` - Mapped to Slack username [${mapping.slackUsername}] but no Slack user with this name/display_name/real_name was found`,
143220
)
221+
debug(
222+
` - Redacted debug info: Mapped to Slack username [${redact(mapping.slackUsername)}] but no Slack user with this name/display_name/real_name was found`,
223+
)
144224
})
145225

146226
debug(`Attempted to fall back to standard matching methods`)
147227
}
148228
}
149229

150230
// Log standard matchers that were tried
151-
if (userId) debug(`Tried to match userId [${userId}] against Slack user.id fields`)
152-
if (email) debug(`Tried to match email [${email}] against Slack user.profile.email fields`)
153-
if (username)
231+
if (userId) {
232+
debug(`Tried to match userId [${userId}] against Slack user.id fields`)
233+
debug(`Redacted debug info: Tried to match userId [${redact(userId)}] against Slack user.id fields`)
234+
}
235+
236+
if (email) {
237+
debug(`Tried to match email [${email}] against Slack user.profile.email fields`)
238+
debug(`Redacted debug info: Tried to match email [${redact(email)}] against Slack user.profile.email fields`)
239+
}
240+
241+
if (username) {
154242
debug(
155243
`Tried to match username [${username}] against Slack user.profile.email (contains), display_name and real_name fields`,
156244
)
245+
debug(
246+
`Redacted debug info: Tried to match username [${redact(username)}] against Slack user.profile.email (contains), display_name and real_name fields`,
247+
)
248+
}
157249

158250
debug(`Since no Slack user match found, unable to @mention user or use their profile image`)
159251
}

0 commit comments

Comments
 (0)