Skip to content

Commit

Permalink
feat: tweak sign-in page design (#6774)
Browse files Browse the repository at this point in the history
* feat: simplify sign-in page

* redid styling, add brandName & providersLayout

* edit some styling

* remove default value

* tweak

* tweak

* tweak logos

* Update signin.tsx

---------

Co-authored-by: Thang Vu <hi@thvu.dev>
  • Loading branch information
balazsorban44 and ThangHuuVu committed Oct 16, 2023
1 parent c4ad77b commit 9af5887
Show file tree
Hide file tree
Showing 112 changed files with 837 additions and 624 deletions.
156 changes: 154 additions & 2 deletions apps/dev/sveltekit/src/hooks.server.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,159 @@
import { SvelteKitAuth } from "@auth/sveltekit"
import GitHub from "@auth/core/providers/github"
import { GITHUB_ID, GITHUB_SECRET } from "$env/static/private"
import Credentials from "@auth/core/providers/credentials"
import Facebook from "@auth/core/providers/facebook"
import Auth0 from "@auth/core/providers/auth0"
import Discord from "@auth/core/providers/discord"
import Email from "@auth/core/providers/email"
import Google from "@auth/core/providers/google"
import Twitter from "@auth/core/providers/twitter"
import LinkedIn from "@auth/core/providers/linkedin"
import Instagram from "@auth/core/providers/instagram"
import Okta from "@auth/core/providers/okta"
import Apple from "@auth/core/providers/apple"
import Slack from "@auth/core/providers/slack"
import Twitch from "@auth/core/providers/twitch"
import Cognito from "@auth/core/providers/cognito"
import AzureAD from "@auth/core/providers/azure-ad"
import Reddit from "@auth/core/providers/reddit"
import Spotify from "@auth/core/providers/spotify"
import {
GITHUB_ID,
GITHUB_SECRET,
FACEBOOK_ID,
FACEBOOK_SECRET,
AUTH0_ID,
AUTH0_SECRET,
AUTH0_ISSUER,
DISCORD_ID,
DISCORD_SECRET,
GOOGLE_ID,
GOOGLE_SECRET,
TWITTER_ID,
TWITTER_SECRET,
LINKEDIN_ID,
LINKEDIN_SECRET,
INSTAGRAM_ID,
INSTAGRAM_SECRET,
OKTA_ID,
OKTA_SECRET,
OKTA_ISSUER,
APPLE_ID,
APPLE_SECRET,
SLACK_ID,
SLACK_SECRET,
TWITCH_ID,
TWITCH_SECRET,
COGNITO_ID,
COGNITO_SECRET,
COGNITO_ISSUER,
AZURE_AD_ID,
AZURE_AD_SECRET,
REDDIT_ID,
REDDIT_SECRET,
SPOTIFY_ID,
SPOTIFY_SECRET,
} from "$env/static/private"
import { TestAdapter } from "$lib/adapter"

const db: Record<string, any> = {}

const adapter = TestAdapter({
getItem(key) {
return db[key]
},
setItem: function (key: string, value: string): Promise<void> {
db[key] = value
return Promise.resolve()
},
deleteItems: function (...keys: string[]): Promise<void> {
keys.forEach((key) => delete db[key])
return Promise.resolve()
},
})
export const handle = SvelteKitAuth({
providers: [GitHub({ clientId: GITHUB_ID, clientSecret: GITHUB_SECRET })],
adapter,
session: {
strategy: "jwt",
},
providers: [
Email({ server: "smtp://127.0.0.1:1025?tls.rejectUnauthorized=false" }),
Credentials({
credentials: { password: { label: "Password", type: "password" } },
async authorize(credentials) {
if (credentials.password !== "pw") return null
return {
name: "Fill Murray",
email: "bill@fillmurray.com",
image: "https://www.fillmurray.com/64/64",
id: "1",
foo: "",
}
},
}),
Google({
clientId: GOOGLE_ID,
clientSecret: GOOGLE_SECRET,
}),
Facebook({ clientId: FACEBOOK_ID, clientSecret: FACEBOOK_SECRET }),
GitHub({ clientId: GITHUB_ID, clientSecret: GITHUB_SECRET }),
Discord({
clientId: DISCORD_ID,
clientSecret: DISCORD_SECRET,
}),
Twitter({
clientId: TWITTER_ID,
clientSecret: TWITTER_SECRET,
}),
Slack({
clientId: SLACK_ID,
clientSecret: SLACK_SECRET,
}),
LinkedIn({
clientId: LINKEDIN_ID,
clientSecret: LINKEDIN_SECRET,
}),
Okta({
clientId: OKTA_ID,
clientSecret: OKTA_SECRET,
issuer: OKTA_ISSUER,
}),
Apple({
clientId: APPLE_ID,
clientSecret: APPLE_SECRET,
}),
Auth0({
clientId: AUTH0_ID,
clientSecret: AUTH0_SECRET,
issuer: AUTH0_ISSUER,
}),
Spotify({
clientId: SPOTIFY_ID,
clientSecret: SPOTIFY_SECRET,
}),
Instagram({
clientId: INSTAGRAM_ID,
clientSecret: INSTAGRAM_SECRET,
}),
Cognito({
clientId: COGNITO_ID,
clientSecret: COGNITO_SECRET,
issuer: COGNITO_ISSUER,
}),
Twitch({
clientId: TWITCH_ID,
clientSecret: TWITCH_SECRET,
}),
Reddit({
clientId: REDDIT_ID,
clientSecret: REDDIT_SECRET,
}),
AzureAD({
clientId: AZURE_AD_ID,
clientSecret: AZURE_AD_SECRET,
}),
],
theme: {
logo: "https://authjs.dev/img/logo/logo-sm.webp",
},
})
186 changes: 186 additions & 0 deletions apps/dev/sveltekit/src/lib/adapter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/**
* Mock adapter for testing
*/

import type {
Adapter,
AdapterUser,
AdapterAccount,
AdapterSession,
} from "@auth/core/adapters"
import type { Awaitable } from "@auth/core/types"

export const options = {
baseKeyPrefix: "",
accountKeyPrefix: "user:account:",
accountByUserIdPrefix: "user:account:by-user-id:",
emailKeyPrefix: "user:email:",
sessionKeyPrefix: "user:session:",
sessionByUserIdKeyPrefix: "user:session:by-user-id:",
userKeyPrefix: "user:",
verificationTokenKeyPrefix: "user:token:",
}

export type DB = {
getItem: (key: string) => Awaitable<any>
setItem: (key: string, value: string) => Awaitable<void>
deleteItems: (...keys: string[]) => Awaitable<void>
}

export function TestAdapter(client: DB): Adapter {
const { baseKeyPrefix } = options
const accountKeyPrefix = baseKeyPrefix + options.accountKeyPrefix
const accountByUserIdPrefix = baseKeyPrefix + options.accountByUserIdPrefix
const emailKeyPrefix = baseKeyPrefix + options.emailKeyPrefix
const sessionKeyPrefix = baseKeyPrefix + options.sessionKeyPrefix
const sessionByUserIdKeyPrefix =
baseKeyPrefix + options.sessionByUserIdKeyPrefix
const userKeyPrefix = baseKeyPrefix + options.userKeyPrefix
const verificationTokenKeyPrefix =
baseKeyPrefix + options.verificationTokenKeyPrefix

const setObjectAsJson = async (key: string, obj: any) =>
await client.setItem(key, JSON.stringify(obj))

const setAccount = async (id: string, account: AdapterAccount) => {
const accountKey = accountKeyPrefix + id
await setObjectAsJson(accountKey, account)
await client.setItem(accountByUserIdPrefix + account.userId, accountKey)
return account
}

const getAccount = async (id: string) => {
const account = await client.getItem(accountKeyPrefix + id)
if (!account) return null
return account
}

const setSession = async (
id: string,
session: AdapterSession
): Promise<AdapterSession> => {
const sessionKey = sessionKeyPrefix + id
await setObjectAsJson(sessionKey, session)
await client.setItem(sessionByUserIdKeyPrefix + session.userId, sessionKey)
return session
}

const getSession = async (id: string) => {
const session = await client.getItem(sessionKeyPrefix + id)
if (!session) return null
return session
}

const setUser = async (
id: string,
user: AdapterUser
): Promise<AdapterUser> => {
await setObjectAsJson(userKeyPrefix + id, user)
await client.setItem(`${emailKeyPrefix}${user.email as string}`, id)
return user
}

const getUser = async (id: string) => {
const user = await client.getItem(userKeyPrefix + id)
if (!user) return null
return user
}

return {
async createUser(user) {
const id = crypto.randomUUID()
// TypeScript thinks the emailVerified field is missing
// but all fields are copied directly from user, so it's there
return await setUser(id, { ...user, id })
},
getUser,
async getUserByEmail(email) {
const userId = await client.getItem(emailKeyPrefix + email)
if (!userId) {
return null
}
return await getUser(userId)
},
async getUserByAccount(account) {
const dbAccount = await getAccount(
`${account.provider}:${account.providerAccountId}`
)
if (!dbAccount) return null
return await getUser(dbAccount.userId)
},
async updateUser(updates) {
const userId = updates.id as string
const user = await getUser(userId)
return await setUser(userId, { ...(user as AdapterUser), ...updates })
},
async linkAccount(account) {
const id = `${account.provider}:${account.providerAccountId}`
return await setAccount(id, { ...account, id })
},
createSession: (session) => setSession(session.sessionToken, session),
async getSessionAndUser(sessionToken) {
const session = await getSession(sessionToken)
if (!session) return null
const user = await getUser(session.userId)
if (!user) return null
return { session, user }
},
async updateSession(updates) {
const session = await getSession(updates.sessionToken)
if (!session) return null
return await setSession(updates.sessionToken, { ...session, ...updates })
},
async deleteSession(sessionToken) {
await client.deleteItems(sessionKeyPrefix + sessionToken)
},
async createVerificationToken(verificationToken) {
await setObjectAsJson(
verificationTokenKeyPrefix +
verificationToken.identifier +
":" +
verificationToken.token,
verificationToken
)
return verificationToken
},
async useVerificationToken(verificationToken) {
const tokenKey =
verificationTokenKeyPrefix +
verificationToken.identifier +
":" +
verificationToken.token

const token = await client.getItem(tokenKey)
if (!token) return null

await client.deleteItems(tokenKey)
return token
},
async unlinkAccount(account) {
const id = `${account.provider}:${account.providerAccountId}`
const dbAccount = await getAccount(id)
if (!dbAccount) return
const accountKey = `${accountKeyPrefix}${id}`
await client.deleteItems(
accountKey,
`${accountByUserIdPrefix} + ${dbAccount.userId as string}`
)
},
async deleteUser(userId) {
const user = await getUser(userId)
if (!user) return
const accountByUserKey = accountByUserIdPrefix + userId
const accountKey = await client.getItem(accountByUserKey)
const sessionByUserIdKey = sessionByUserIdKeyPrefix + userId
const sessionKey = await client.getItem(sessionByUserIdKey)
await client.deleteItems(
userKeyPrefix + userId,
`${emailKeyPrefix}${user.email as string}`,
accountKey as string,
accountByUserKey,
sessionKey as string,
sessionByUserIdKey
)
},
}
}
2 changes: 1 addition & 1 deletion docs/static/img/providers/apple-dark.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion docs/static/img/providers/apple.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions docs/static/img/providers/asgardeo-dark.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions docs/static/img/providers/asgardeo.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 2 additions & 6 deletions docs/static/img/providers/atlassian-dark.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

1 comment on commit 9af5887

@vercel
Copy link

@vercel vercel bot commented on 9af5887 Oct 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.