Experimenting with Cognito to build a CLI tool
Here is the code to implement a secure frontend first (and only) authentication flow with Cognito User Pool
// https://docs.aws.amazon.com/cognito/latest/developerguide/logout-endpoint.html
// https://docs.aws.amazon.com/cognito/latest/developerguide/login-endpoint.html
import { type Context, Hono } from "hono";
import { logger } from "hono/logger";
import { ContentfulStatusCode } from "hono/utils/http-status";
import open from "npm:open";
const app = new Hono();
app.use(logger());
let user!: {
token_type: "bearer";
expires_in: number;
refresh_token: string;
access_token: string;
id_token: string;
};
const domain =
"https://<YOUR-COGNITO-USER-POOL-ID>.auth.ca-central-1.amazoncognito.com";
const cognitoAuthConfig = {
client_id: "<YOUR-CLIENT-ID>",
redirect_uri: "http://localhost:13567/redirect_uri",
response_type: "code",
scope: "email+openid+phone", // add what you need for your application
};
const loginUrl = `${domain}/login?client_id=${cognitoAuthConfig.client_id}&redirect_uri=${encodeURIComponent(cognitoAuthConfig.redirect_uri)}&response_type=${cognitoAuthConfig.response_type}&scope=${cognitoAuthConfig.scope}`;
console.log("Login URL", loginUrl);
open(loginUrl);
app.get("/redirect_uri", async (c: Context) => {
console.log("received", c.req.url);
const { code } = c.req.query();
const tokens = await fetch(
`${domain}/oauth2/token?grant_type=authorization_code&client_id=${cognitoAuthConfig.client_id}&redirect_uri=${encodeURIComponent(cognitoAuthConfig.redirect_uri)}&code=${code}&scope=${cognitoAuthConfig.scope}`,
{
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
},
);
if (tokens.ok) {
console.log(await tokens.json());
user = await tokens.json();
return c.text("Ok");
}
return c.text("Not Ok", (tokens.status as ContentfulStatusCode) || 500);
});
app.onError((err: Error, c: Context) => {
console.error("GLOBAL ERROR HANDLING", err);
return c.text("not ok", 500);
});
Deno.serve({ port: 13567, hostname: "0.0.0.0" }, app.fetch);