Skip to content

Commit

Permalink
Get passkey endpoints (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mikescops authored Feb 28, 2024
1 parent aa1d04b commit e62b51c
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 10 deletions.
1 change: 1 addition & 0 deletions website/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ yarn-error.log*
next-env.d.ts

public/domains.json
public/icons/
3 changes: 3 additions & 0 deletions website/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ module.exports = {
output: 'export',
assetPrefix: assetPrefix,
basePath: basePath,
images: {
unoptimized: true
}
};
7 changes: 7 additions & 0 deletions website/public/enroll.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 3 additions & 7 deletions website/public/link.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions website/public/manage.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 55 additions & 2 deletions website/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import emptyIcon from "../../public/link.svg";
import passkeyIcon from "../../public/passkey.svg";
import searchIcon from "../../public/search.svg";
import dashlaneIcon from "../../public/dashlane.svg";
import enrollIcon from "../../public/enroll.svg";
import manageIcon from "../../public/manage.svg";

type SortedField = "domain" | "name";

Expand Down Expand Up @@ -99,6 +101,12 @@ const Page = () => {
<th className="px-6 py-3 bg-gray-50 dark:bg-slate-700 dark:text-white text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
Description
</th>
<th className="px-6 py-3 bg-gray-50 dark:bg-slate-700 dark:text-white text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
Enroll
</th>
<th className="px-6 py-3 bg-gray-50 dark:bg-slate-700 dark:text-white text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
Manage
</th>
</tr>
</thead>
<tbody className="bg-white dark:bg-slate-800 divide-y divide-gray-200 dark:divide-gray-600">
Expand All @@ -109,13 +117,24 @@ const Page = () => {
>
<td className="px-6 py-4 whitespace-no-wrap">
{item.icon !== "" ? (
<img src={item.icon} alt={item.name} className="h-8 w-8" />
<Image
src={item.icon}
alt={item.name}
width={32}
height={32}
className="h-8 w-8"
/>
) : (
<Image src={emptyIcon} alt={item.name} className="h-8 w-8" />
)}
</td>
<td className="px-6 py-4 whitespace-no-wrap">
<a href={"https://" + item.domain} rel="nofollow" target="_blank">
<a
href={"https://" + item.domain}
rel="nofollow"
target="_blank"
className="hover:underline "
>
{item.domain}
</a>
</td>
Expand All @@ -125,6 +144,40 @@ const Page = () => {
: item.domain.charAt(0).toUpperCase() + item.domain.slice(1)}
</td>
<td className="px-6 py-4 whitespace-no-wrap">{item.description}</td>
<td className="px-6 py-4 whitespace-no-wrap text-center">
{item.endpoints.enroll !== "" && (
<a
href={item.endpoints.enroll}
rel="nofollow"
target="_blank"
title={item.endpoints.enroll}
>
<Image
className="inline hover:opacity-70"
alt="Enroll icon"
height={25}
src={enrollIcon}
/>
</a>
)}
</td>
<td className="px-6 py-4 whitespace-no-wrap text-center">
{item.endpoints.manage !== "" && (
<a
href={item.endpoints.manage}
rel="nofollow"
target="_blank"
title={item.endpoints.manage}
>
<Image
className="inline hover:opacity-70"
alt="Manage icon"
height={25}
src={manageIcon}
/>
</a>
)}
</td>
</tr>
))}
</tbody>
Expand Down
35 changes: 34 additions & 1 deletion website/tools/fetch-domains.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,29 @@ async function fetchDomainInfo(domain, debug = false) {

const bestQualityIcon = await findBestAccessibleIcon(icons, debug);

let iconPath = '';
// save the icon locally
if (bestQualityIcon !== null && bestQualityIcon !== '') {
console.log("Fetching icon from:", bestQualityIcon);
const response = await axiosInstance.get(bestQualityIcon, { responseType: 'arraybuffer' });
const fileExtension = bestQualityIcon.split('.').pop();
// if icon folder does not exist, create it
fs.access('public/icons').catch(() => {
fs.mkdir('public/icons');
});
iconPath = `icons/${domain}.${fileExtension}`;
await fs.writeFile(`public/${iconPath}`, response.data);
if (debug) console.log(`Icon saved to ${iconPath}`);
}

const wellKnownEndpoints = await getWellKnownEndpoints(url.hostname, debug);

return {
domain, // Add the domain to the output
name: title,
description,
icon: bestQualityIcon,
icon: iconPath,
endpoints: wellKnownEndpoints,
};
} catch (error) {
if (debug) {
Expand All @@ -85,10 +103,25 @@ async function fetchDomainInfo(domain, debug = false) {
name: '',
description: '',
icon: '',
endpoints: { enroll: '', manage: '' },
};
}
}

async function getWellKnownEndpoints(baseUrl, debug = false) {
const url = `https://${baseUrl}/.well-known/passkey-endpoints`;
console.log("Fetching passkey endpoints from:", url);
try {
const response = await axiosInstance.get(url);
return { enroll: response.data.enroll ?? '', manage: response.data.manage ?? '' };
} catch (error) {
if (debug) {
console.error(`Error fetching well-known endpoints for domain ${baseUrl}:`, error);
}
return { enroll: '', manage: '' };
}
}

async function getIcons(document, baseUrl, debug = false) {
const icons = [];

Expand Down

0 comments on commit e62b51c

Please sign in to comment.