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

feat: updated join logic to use auth.js and be a nicer experience #9

Merged
merged 3 commits into from
Apr 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion src/components/AuthContainer.astro
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type ExtendedSession = {
<Auth>
{
(session: Session & ExtendedSession) => {
if (session) {
if (session && session.user.role !== "guest") {
return (
<div class="signed-in-container">
<div class="top">
Expand Down Expand Up @@ -51,6 +51,32 @@ type ExtendedSession = {
</div>
</div>
);
} else if (session && session.user.role === "guest") {
return (
<div class="signed-in-container">
<div class="top">
<a href="dashboard">
<img src={`${session.user?.image}`} alt="" />
</a>
<div class="text-centered">
<p>
Welcome,{" "}
{session.user?.name}!
</p>
<p>{session.user?.email}</p>
</div>
<SignOut params={{ callbackUrl: "/" }}>Sign Out</SignOut>
</div>
<div class="bottom text-centered">
<h2>{session.teamName}</h2>
<nav>
<a href="/join" class="nav">
if you have a join code click here.
</a>
</nav>
</div>
</div>
)
} else {
return (
<div class="signed-out-container">
Expand Down
97 changes: 0 additions & 97 deletions src/pages/api/newTeam.ts

This file was deleted.

102 changes: 52 additions & 50 deletions src/pages/join/[joinCode].astro
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
---
import Base from "../../Layouts/Base.astro";
import AuthContainer from "../../components/AuthContainer.astro";
import { SignIn } from "auth-astro/components";

import { getSession } from "auth-astro/server";
import { type Session } from "@auth/core/types";
import { db } from "astro:db";
import { Invite } from "astro:db";
import { like } from "astro:db";
import { Organization } from "astro:db";

type ExtendedSession = {
team: string;
Expand All @@ -19,9 +20,9 @@ type ExtendedSession = {

const session = (await getSession(Astro.request)) as Session & ExtendedSession;

if (session) {
if (session && session.user.role !== "guest") {
const error = "authorization_error";
const errorDescription = "You are already signed in to MagicSnap!";
const errorDescription = "You are already signed in to a valid team!";
const queryParams = new URLSearchParams({ error, errorDescription });
const redirectUrl = `/error?${queryParams.toString()}`;

Expand All @@ -33,11 +34,9 @@ if (session) {
});
}

const url = Astro.url.origin;
const joinCode = Astro.params.joinCode;
const verification = Astro.url.searchParams.get("verification");

if (!joinCode || joinCode === "index.html") {
if (!joinCode) {
const error = "join_code_error";
const errorDescription = "No join code provided!";
const queryParams = new URLSearchParams({ error, errorDescription });
Expand Down Expand Up @@ -69,55 +68,58 @@ if (!team) {
});
}

const toRedirect = verification === team.installationToken;

if (toRedirect) {
if (session && session.user.role === "guest") {
await db.delete(Invite).where(like(Invite.verificationCode, joinCode));
await db.insert(Organization).values({
team: session.team,
name: session.teamName,
image: session.teamImage,
});
}
---

<Base title="Connect your teams acount to MagicSnap!">
{ !toRedirect && (
<section>
<p>
Thanks for signing your team {team.teamName} up for MagicSnap! To get started,
you'll need to connect your Slack workspace to MagicSnap. This will allow us
to enable sign-in with Slack, and to access your team's profile information.
</p>
</section>
<section class="slack-button">
<a
href=`https://slack.com/oauth/v2/authorize?scope=team%3Aread%2Cusers%3Aread%2Cusers%3Aread.email%2Cusers.profile%3Aread&user_scope=openid%2Cprofile%2Cemail&redirect_uri=${url}%2Fapi%2FnewTeam&client_id=78959039506.6869041606981&state=${joinCode}`
style="align-items:center;color:#000;background-color:#fff;border:1px solid #ddd;border-radius:4px;display:inline-flex;font-family:Lato, sans-serif;font-size:16px;font-weight:600;height:48px;justify-content:center;text-decoration:none;width:236px"
><svg
xmlns="http://www.w3.org/2000/svg"
style="height:20px;width:20px;margin-right:12px"
viewBox="0 0 122.8 122.8"
><path
d="M25.8 77.6c0 7.1-5.8 12.9-12.9 12.9S0 84.7 0 77.6s5.8-12.9 12.9-12.9h12.9v12.9zm6.5 0c0-7.1 5.8-12.9 12.9-12.9s12.9 5.8 12.9 12.9v32.3c0 7.1-5.8 12.9-12.9 12.9s-12.9-5.8-12.9-12.9V77.6z"
fill="#e01e5a"></path><path
d="M45.2 25.8c-7.1 0-12.9-5.8-12.9-12.9S38.1 0 45.2 0s12.9 5.8 12.9 12.9v12.9H45.2zm0 6.5c7.1 0 12.9 5.8 12.9 12.9s-5.8 12.9-12.9 12.9H12.9C5.8 58.1 0 52.3 0 45.2s5.8-12.9 12.9-12.9h32.3z"
fill="#36c5f0"></path><path
d="M97 45.2c0-7.1 5.8-12.9 12.9-12.9s12.9 5.8 12.9 12.9-5.8 12.9-12.9 12.9H97V45.2zm-6.5 0c0 7.1-5.8 12.9-12.9 12.9s-12.9-5.8-12.9-12.9V12.9C64.7 5.8 70.5 0 77.6 0s12.9 5.8 12.9 12.9v32.3z"
fill="#2eb67d"></path><path
d="M77.6 97c7.1 0 12.9 5.8 12.9 12.9s-5.8 12.9-12.9 12.9-12.9-5.8-12.9-12.9V97h12.9zm0-6.5c-7.1 0-12.9-5.8-12.9-12.9s5.8-12.9 12.9-12.9h32.3c7.1 0 12.9 5.8 12.9 12.9s-5.8 12.9-12.9 12.9H77.6z"
fill="#ecb22e"></path></svg
>Add to Slack</a
>
</section>
) }
{ toRedirect && (
<section>
<p>
You have successfully connected your team {team.teamName} to MagicSnap! You
can now sign in to MagicSnap using your Slack account. You will be redirected
to the MagicSnap homepage after signing in.
</p>
</section>
<section>
<AuthContainer />
</section>
) }
{
!session && (
<>
<section>
<p>
Thanks for signing your team {team.teamName} up for MagicSnap! To
get started, you'll need to connect your Slack workspace to
MagicSnap. This will allow us to enable sign-in with Slack, and to
access your team's profile information.
</p>
</section>
<section class="slack-button">
<SignIn
provider="slack"
options={{ callbackUrl: `/join/${joinCode}` }}
>
Connect your Slack Workspace
</SignIn>
</section>
</>
)
}
{
session && session.user.role === "guest" && (
<>
<section>
<p>
You have successfully connected your team {team.teamName} to
MagicSnap! You can now sign in to MagicSnap using your Slack account
and you will be redirected to your team's dashboard as the team
owner.
</p>
</section>
<section class="slack-button">
<SignIn provider="slack" options={{ callbackUrl: `/dashboard` }}>
Sign In
</SignIn>
</section>
</>
)
}
</Base>

<style>
Expand Down
85 changes: 85 additions & 0 deletions src/pages/join/index.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
import Base from "../../Layouts/Base.astro";
import { getSession } from "auth-astro/server";
import { type Session } from "@auth/core/types";

type ExtendedSession = {
team: string;
teamName: string;
teamImage: string;
user: {
role: string;
};
};

const session = (await getSession(Astro.request)) as Session & ExtendedSession;

if (session && session.user.role !== "guest") {
const error = "authorization_error";
const errorDescription = "You are already signed in to a valid team!";
const queryParams = new URLSearchParams({ error, errorDescription });
const redirectUrl = `/error?${queryParams.toString()}`;

return new Response(null, {
status: 302,
headers: new Headers({
Location: redirectUrl,
}),
});
}
---

<Base title="Join">
<section>
<p>
Hi! If you got here because you have a join code please enter it in the
form below. Otherwise if you would like to start using MagicSnap for your
team you can join our <u
><a href="https://discord.gg/NGWFZg5Fgn">Discord</a></u
> and ask for an invite and we would be happy to help you get started!
</p>
</section>
<section class="joinCodeForm">
<input type="text" name="codeInput" placeholder="Enter code here" />
<a href="/join"><button>Join</button></a>
</section>
</Base>

<style>
.joinCodeForm {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.joinCodeForm input {
margin: 1rem;
padding: 0.5rem;
}
.joinCodeForm button {
margin-top: 0;
}
</style>

<script>
const form = document.querySelector(".joinCodeForm");
const input = form?.querySelector("input");
const link = form?.querySelector("a");

input?.addEventListener("input", async () => {
const code = input?.value;
if (code) {
link?.setAttribute("href", `/join/${code}`);
}
});

input?.addEventListener("keydown", (event) => {
if (event.key === "Enter") {
event.preventDefault();
const code = input?.value;
if (code) {
window.location.href = `/join/${code}`;
}
}
});
</script>
Loading