Skip to content

Instantly share code, notes, and snippets.

@eai04191
Last active February 9, 2023 07:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eai04191/5c751e58375ba375bef3c1283cedd0ea to your computer and use it in GitHub Desktop.
Save eai04191/5c751e58375ba375bef3c1283cedd0ea to your computer and use it in GitHub Desktop.

GitHubの2FAを有効にしていない人を一覧したいけどどのリポジトリにアクセスできるのか調べるのめんどくさいときに使うスニペット

https://github.com/orgs/YOUR_ORG_HERE/outside-collaborators?query=two-factor%3Adisabled

みたいなURLで2FAしてないOutside Collaboratorsの一覧が見れるのでJSを実行すると

[example-user-01](https://github.com/orgs/YOUR_ORG_HERE/people/example-user-01):
  [YOUR_ORG_HERE/example-repo-01](https://github.com/YOUR_ORG_HERE/example-repo-01)
  [YOUR_ORG_HERE/example-repo-02](https://github.com/YOUR_ORG_HERE/example-repo-02)
[example-user-02](https://github.com/orgs/YOUR_ORG_HERE/people/example-user-02):
  [YOUR_ORG_HERE/example-repo-02](https://github.com/YOUR_ORG_HERE/example-repo-02)

みたいなmarkdownが取れるのでSlackに貼ってなんとかしてって言う

ページングは無視されるのでうまいことやってくれ

const org = "YOUR_ORG_HERE";
const data = await Promise.all(
[...document.querySelectorAll(`.member-info`)]
.map((e) =>
e.querySelector(`[itemprop="name"]`)
? e.querySelector(`[itemprop="name"]`).innerText
: e.innerText
)
.map(
async (id) =>
await fetch(`https://github.com/orgs/${org}/people/${id}`)
.then((res) => res.text())
.then((html) => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
const repos = [...doc.querySelectorAll(`.js-org-repo`)].map(
(e) => e.querySelector(`a`).href
);
return { id, repos };
})
)
);
let text = "";
data.forEach((d) => {
text += `[${d.id}](https://github.com/orgs/${org}/people/${d.id}):\n`;
d.repos.forEach((r) => {
text += ` [${r.replace("https://github.com/", "")}](${r})\n`;
});
});
console.log(text);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment