Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation: Usage in (plain) web #1

Open
Vlaaaaaaad opened this issue Mar 21, 2023 · 4 comments
Open

Documentation: Usage in (plain) web #1

Vlaaaaaaad opened this issue Mar 21, 2023 · 4 comments

Comments

@Vlaaaaaaad
Copy link

Hi,

Awesome sample code y'all built here ❣️ Thank you!

As somebody that's considering using Cognito in a plain/vanilla-JavaScript project, I'd really appreciate the still-to-be-written docs. I am creating this issue to show/track demand 🙂

> **_Oops:_** These docs still need to be written :( For now, your best best is looking at the [React docs](./react/README-REACT.md).

@ottokruse
Copy link
Contributor

ottokruse commented Mar 21, 2023

Thanks for your interest! Yes we should really document this.

Here a super quick braindump to get you started, might you be so brave:

--

This will be the same in plain web:

import { Passwordless } from "amazon-cognito-passwordless-auth";

Passwordless.configure({
  cognitoIdpEndpoint:
    "<AWS region where the CDK stack was deployed to, e.g. eu-west-1>",
  clientId:
    "<Cognito User Pool Client ID, one of the outputs of the CDK stack>",
  fido2: {
    baseUrl:
      "<The base URL to the FIDO2 API, one of the outputs of the CDK stack>",
  },
  debug: console.debug, // Optional: adds logging
});

And then you can import from the respective files, e.g. for magic link:

import { requestSignInLink, signInWithLink } from "amazon-cognito-passwordless-auth/magic-link";

// somewhere in your web app, e.g. in a button on-click handler, you request the magic link:
const { signInLinkRequested } = requestSignInLink({ username: "alice" });
try {
  await signInLinkRequested;
  console.log("We've emailed you a secret sign-in link")
} catch(err) {
  console.log("Oops", err)
}

// on load of your web app, you catch the magic link
// (this is a no-op if there is no magic link in the browser URL bar)
const { signedIn } = signInWithLink({
  statusCb: console.log, // will log e.g. SIGNED_IN_WITH_LINK, NO_SIGNIN_LINK, SIGNIN_LINK_EXPIRED, ...
});
await signedIn; // This promise resolves once sign-in completes (or if it was a no-op)

The status logged by the statusCb above is the status of the sign in process, i.e. the process of signing in with magic link in this case.

The signedIn promise resolves also if there's nothing to do (e.g. because there's no sign in link in the URL). So it doesn't necessarily mean that the user is signed in after this promise resolves.

To determine the active sign-in status, i.e. is the user currently signed in or not, you should simply check the JWTs in storage. If you have valid JWTs you are signed in. For ease you can just check the expireAt field which should cover it, but you could also actually verify the JWTs:

import { retrieveTokens } from "amazon-cognito-passwordless-auth/storage";

const tokens = await retrieveTokens();
if (tokens && tokens.expireAt > new Date()) {
  console.log("Looks like the user is signed in");
}

See also the React code, which works just like that, but covers more nuances:

const signInStatus = useMemo(() => {
recheckSignInStatus; // dummy usage otherwise eslint complains we should remove it from the dep array
return tokensParsed && tokensParsed.expireAt.valueOf() >= Date.now()
? ("SIGNED_IN" as const)
: tokensParsed && (isSchedulingRefresh || isRefreshingTokens)
? ("REFRESHING_SIGN_IN" as const)
: busyState
.filter(
(state) =>
!["SIGNING_OUT", "CHECKING_FOR_SIGNIN_LINK"].includes(state)
)
.includes(signingInStatus as BusyState)
? ("SIGNING_IN" as const)
: initiallyRetrievingTokensFromStorage ||
signingInStatus === "CHECKING_FOR_SIGNIN_LINK"
? ("CHECKING" as const)
: signingInStatus === "SIGNING_OUT"
? ("SIGNING_OUT" as const)
: ("NOT_SIGNED_IN" as const);
}, [

@HasseJohansen
Copy link

HasseJohansen commented Jun 9, 2023

Hi

Thank you for building this

I am also trying to use this from plain javascript(I am not experienced writting javascript and I don't know react)

I do get a successful login with a magic link following your example (after changing username to usernameOrAlias)

But how do I track the logged in state? it doesn't seem like signInWithLink() (and by that signedIn) is tracking that and as I can see a comment in the React code telling that signInWithLink without a magic link is a no-op will it ever then reach catch in this example? Because having:

const { signedIn } = signInWithLink();
try {
  await signedIn;
  console.log("You made it in!")
} catch(err) {
  console.log("Oops", err)
}

Will just forever hit the console.log("You made it in!")

And that even after I delete all the tokens in local storage

In the React code it seems like you pass a statusCb and tokensCb. Can I do something similar?

@ottokruse
Copy link
Contributor

ottokruse commented Jun 9, 2023

You're right you need to use the statusCb for that. I updated my example to show. Let me know if that helps.

@menkari
Copy link

menkari commented Aug 27, 2024

Has anyone here taken a stab at porting hooks to an appropriate angular service? I'm looking to port this across with some of the niceties of the scheduling token refresh etc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants