Compare commits

...

34 Commits

Author SHA1 Message Date
Balázs Orbán
53f41d637a birthday single word 2022-12-31 08:45:25 +01:00
Balázs Orbán
e910c90525 update in core 2022-12-31 08:43:00 +01:00
박찬혁
2004a377ea Merge branch 'main' into feat-kakao-type-safety 2022-12-25 23:57:14 +09:00
Thang Vu
ae57199258 chore(examples): unify /protected path behavior for Sveltekit and N… (#6176)
chore(examples): unify `/protected` path behavior for Sveltekit and Next.js
2022-12-25 17:56:10 +07:00
Balázs Orbán
aad425fced docs: show property types 2022-12-25 09:53:53 +01:00
Balázs Orbán
8ef1010bb1 chore: attempt to fix supabase test
SUPABASE_SERVICE_ROLE_KEY could be an empty string
2022-12-25 06:38:29 +01:00
Balázs Orbán
950ca3169a chore: make supabase wget quite 2022-12-25 06:30:03 +01:00
Balázs Orbán
edbf0fc011 chore: revert concurrency 2022-12-25 06:19:20 +01:00
Balázs Orbán
46bac818fe chore: add concurrency to tests 2022-12-25 06:15:48 +01:00
Balázs Orbán
9e64eb0cdd chore: simplify turbo config 2022-12-25 06:15:27 +01:00
Balázs Orbán
955e379330 chore: format 2022-12-25 05:59:12 +01:00
Balázs Orbán
7be4461253 chore: don't minify output CSS 2022-12-25 05:58:43 +01:00
Balázs Orbán
c2e06dc445 chore: upgrade oauth4webapi 2022-12-25 05:58:08 +01:00
Balázs Orbán
4dd70a5f6f fix(ts): enable strict type checking 2022-12-25 05:55:25 +01:00
Balázs Orbán
98dbf56494 Merge branch 'main' of github.com:nextauthjs/next-auth 2022-12-25 05:19:32 +01:00
Balázs Orbán
6b4644f7e7 chore(adapters): refactor Supabase Adapter test 2022-12-25 05:18:53 +01:00
GitHub Actions
bcf909b69e chore(release): bump package version(s) [skip ci] 2022-12-24 16:39:23 +00:00
Balázs Orbán
4dcdd21242 fix(providers): add state check to Twitter by default
Fixes #6135
2022-12-24 17:16:22 +01:00
Balázs Orbán
137d993a13 chore(dev): upgrade next 2022-12-24 17:15:35 +01:00
Balázs Orbán
8dda662cd6 chore: fix issue validator path 2022-12-24 16:43:51 +01:00
Balázs Orbán
8a438bab32 Merge branch 'main' of github.com:nextauthjs/next-auth 2022-12-24 16:36:33 +01:00
Balázs Orbán
4aaad03e9c chore: fix issue validator 2022-12-24 16:36:30 +01:00
Fatih Aygün
4fa0d1fa2a fix(core): correctly normalize endpoint configuration (#6173) 2022-12-24 15:31:47 +00:00
Balázs Orbán
c081773667 chore: use classic PAT for example sync 2022-12-24 15:25:57 +00:00
Balázs Orbán
1ab0a2aed4 fix(adapters): correct peer dependency for Supabase Adapter
Fixes #6172
2022-12-24 15:23:29 +00:00
Balázs Orbán
cac9816d32 chore: update sync examples PAT 2022-12-24 15:19:27 +00:00
Balázs Orbán
65defc709e chore(examples): change to named import 2022-12-24 15:14:06 +00:00
Balázs Orbán
1601626d31 chore: prettier ignore generated file 2022-12-24 04:34:47 +01:00
Balázs Orbán
8c4f439279 fix: add package keywords 2022-12-24 04:32:10 +01:00
박찬혁
f24c91b8ee Merge branch 'main' into feat-kakao-type-safety 2022-12-16 10:06:53 +09:00
박찬혁
ad72985460 Merge branch 'main' into feat-kakao-type-safety 2022-12-15 09:58:22 +09:00
박찬혁
f299954e9b Merge branch 'main' into feat-kakao-type-safety 2022-12-14 13:57:18 +09:00
박찬혁
f325f76c24 Merge branch 'main' into feat-kakao-type-safety 2022-12-13 18:00:42 +09:00
ChanhyukPark-Tech
05d9f1cbee feat: type safety for BirthDay 2022-12-13 17:58:33 +09:00
40 changed files with 501 additions and 729 deletions

File diff suppressed because one or more lines are too long

View File

@@ -526,7 +526,7 @@ IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
root
ISC License
Copyright (c) 2018-2021, Iain Collins
Copyright (c) 2022-2023, Balázs Orbán
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
@@ -540,6 +540,7 @@ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
tr46
MIT

View File

@@ -4,6 +4,7 @@ import * as github from "@actions/github"
// @ts-expect-error
import * as core from "@actions/core"
import { readFileSync } from "node:fs"
import { join } from "node:path"
const addReproductionLabel = "incomplete"
@@ -40,7 +41,13 @@ async function run() {
label: { name: newLabel },
} = payload
if (pull_request || !issue?.body || !process.env.GITHUB_TOKEN) return
if (
pull_request ||
!issue?.body ||
!process.env.GITHUB_TOKEN ||
!process.env.GITHUB_ACTION_PATH
)
return
const labels = issue.labels.map((l) => l.name)
// const isBugReport =
@@ -70,7 +77,10 @@ async function run() {
}),
client.issues.createComment({
...issueCommon,
body: readFileSync("repro.md", "utf8"),
body: readFileSync(
join(process.env.GITHUB_ACTION_PATH, "repro.md"),
"utf8"
),
}),
])
return core.info(

View File

@@ -14,6 +14,6 @@ jobs:
# Can update to v1 when https://github.com/BetaHuhn/repo-file-sync-action/issues/168 is resolved
uses: BetaHuhn/repo-file-sync-action@v1.16.5
with:
GH_PAT: ${{ secrets.SYNC_EXAMPLE_PAT }}
GH_PAT: ${{ secrets.GH_PAT_CLASSIC }}
SKIP_PR: true
ORIGINAL_MESSAGE: true

View File

@@ -23,6 +23,7 @@ build
docs/docs/reference/03-core
docs/docs/reference/04-sveltekit
static
docs/providers.json
# --------------- Packages ---------------

View File

@@ -12,5 +12,11 @@ module.exports = {
],
options: { printWidth: 150 },
},
{
files: ["**/*package.json"],
options: {
trailingComma: "none",
},
},
],
}

View File

@@ -1,4 +1,4 @@
{
"typescript.tsdk": "../../node_modules/.pnpm/typescript@4.8.4/node_modules/typescript/lib",
"typescript.tsdk": "../../node_modules/.pnpm/typescript@4.9.4/node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true
}

View File

@@ -20,7 +20,7 @@
"@prisma/client": "^3",
"@supabase/supabase-js": "^2.0.5",
"faunadb": "^4",
"next": "13.0.6",
"next": "13.1.1",
"next-auth": "workspace:*",
"@auth/core": "workspace:*",
"nodemailer": "^6",

View File

@@ -1,4 +1,11 @@
{
"private": true,
"description": "An example project for Auth.js with SvelteKit",
"repository": "https://github.com/nextauthjs/sveltekit-auth-example",
"bugs": {
"url": "https://github.com/nextauthjs/next-auth/issues"
},
"homepage": "https://sveltekit-auth-example.vercel.app",
"scripts": {
"dev": "vite dev",
"build": "vite build",

View File

@@ -1,4 +1,4 @@
import SvelteKitAuth from "@auth/sveltekit"
import { SvelteKitAuth } from "@auth/sveltekit"
import GitHub from "@auth/core/providers/github"
import { GITHUB_ID, GITHUB_SECRET } from "$env/static/private"

View File

@@ -2,9 +2,18 @@
import { page } from "$app/stores"
</script>
{#if $page.data.session}
<h1>Protected page</h1>
<p>
This is a protected content. You can access this content because you are
signed in.
</p>
<p>Session expiry: {$page.data.session?.expires}</p>
{:else}
<h1>Access Denied</h1>
<p>
<a href="/auth/signin">
You must be signed in to view this page
</a>
</p>
{/if}

View File

@@ -1,10 +0,0 @@
import { redirect } from "@sveltejs/kit"
import type { PageLoad } from "./$types"
export const load: PageLoad = async ({ parent }) => {
const { session } = await parent()
if (!session?.user) {
throw redirect(302, "/")
}
return {}
}

View File

@@ -292,7 +292,7 @@ html[data-theme="dark"] #carbonads .carbon-poweredby {
HACK: to hide the "Classes" header and duplicate items together with the "typedoc-plugin-markdown" patch.
See: https://github.com/TypeStrong/typedoc/issues/2006
*/
#classes,
h3.anchor + p:has(code, strong) {
/* h3.anchor + p:has(code, strong), */ /** hack did not work as it hides property types elsewhere */
#classes {
display: none;
}

View File

@@ -1,6 +1,6 @@
{
"name": "@next-auth/supabase-adapter",
"version": "0.2.0",
"version": "0.2.1",
"description": "Supabase adapter for next-auth.",
"homepage": "https://authjs.dev",
"repository": "https://github.com/nextauthjs/next-auth",
@@ -25,7 +25,7 @@
},
"peerDependencies": {
"@supabase/supabase-js": "^2.0.5",
"next-auth": "workspace:*"
"next-auth": "^4.18.7"
},
"devDependencies": {
"@next-auth/adapter-test": "workspace:^0.0.0",

View File

@@ -8,20 +8,15 @@ import type {
} from "next-auth/adapters"
import type { Account } from "next-auth"
const supabase = createClient(
process.env.SUPABASE_URL ?? "http://localhost:54321",
process.env.SUPABASE_SERVICE_ROLE_KEY ??
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSJ9.vI9obAHOGyVVKa3pD--kJlyxp-Z2zV9UUMAhKpNLAcU",
{ db: { schema: "next_auth" } }
)
const url = process.env.SUPABASE_URL ?? "http://localhost:54321"
const secret =
process.env.SUPABASE_SERVICE_ROLE_KEY ||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSJ9.vI9obAHOGyVVKa3pD--kJlyxp-Z2zV9UUMAhKpNLAcU"
const supabase = createClient(url, secret, { db: { schema: "next_auth" } })
runBasicTests({
adapter: SupabaseAdapter({
url: process.env.SUPABASE_URL ?? "http://localhost:54321",
secret:
process.env.SUPABASE_SERVICE_ROLE_KEY ??
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSJ9.vI9obAHOGyVVKa3pD--kJlyxp-Z2zV9UUMAhKpNLAcU",
}),
adapter: SupabaseAdapter({ url, secret }),
db: {
async session(sessionToken) {
const { data, error } = await supabase

View File

@@ -2,13 +2,13 @@
# install Supabase CLI when run on CI
if [ "$CI" = true ]; then
wget -O supabase.deb https://github.com/supabase/cli/releases/download/v0.29.0/supabase_0.29.0_linux_amd64.deb
wget -q -O supabase.deb https://github.com/supabase/cli/releases/download/v0.29.0/supabase_0.29.0_linux_amd64.deb
sudo dpkg -i supabase.deb
fi
# Start Supabase, grep key and set it as SUPABASE_SERVICE_ROLE_KEY environment variable
line=$(supabase start | grep 'service_role key')
IFS=':'; arr=($line); unset IFS;
IFS=':'; arr=("$line"); unset IFS;
export SUPABASE_SERVICE_ROLE_KEY=${arr[1]}
# Always stop Supabase, but exit with 1 when tests are failing

View File

@@ -1,7 +1,18 @@
{
"name": "@auth/core",
"version": "0.2.2",
"description": "Authentication for the web.",
"version": "0.2.3",
"description": "Authentication for the Web.",
"keywords": [
"authentication",
"authjs",
"jwt",
"oauth",
"oidc",
"passwordless",
"standard",
"vanilla",
"webapi"
],
"homepage": "https://authjs.dev",
"repository": "https://github.com/nextauthjs/next-auth.git",
"author": "Balázs Orbán <info@balazsorban.com>",
@@ -53,7 +64,7 @@
"@panva/hkdf": "1.0.2",
"cookie": "0.5.0",
"jose": "4.11.1",
"oauth4webapi": "2.0.5",
"oauth4webapi": "2.0.6",
"preact": "10.11.3",
"preact-render-to-string": "5.2.3"
},
@@ -66,19 +77,19 @@
}
},
"scripts": {
"build": "pnpm clean && pnpm css && tsc",
"clean": "rm -rf *.js *.d.ts lib providers",
"css": "node ./scripts/generate-css.js",
"build": "pnpm css && tsc",
"clean": "rm -rf *.js *.d.ts* lib providers",
"css": "node scripts/generate-css",
"dev": "pnpm css && tsc -w"
},
"devDependencies": {
"@next-auth/tsconfig": "workspace:*",
"@types/cookie": "0.5.1",
"@types/node": "18.11.10",
"@types/nodemailer": "6.4.6",
"@types/react": "18.0.26",
"autoprefixer": "10.4.13",
"cssnano": "5.1.14",
"postcss": "8.4.19",
"postcss-nested": "6.0.0"
}
}
}

View File

@@ -4,7 +4,6 @@ import postcss from "postcss"
import autoprefixer from "autoprefixer"
import postCssNested from "postcss-nested"
import cssNano from "cssnano"
const from = path.join(process.cwd(), "src/lib/pages/styles.css")
const css = fs.readFileSync(from)
@@ -12,7 +11,6 @@ const css = fs.readFileSync(from)
const processedCss = await postcss([
autoprefixer,
postCssNested,
cssNano({ preset: "default" }),
]).process(css, { from })
fs.writeFileSync(

View File

@@ -129,11 +129,13 @@ export function assertConfig(
return new MissingAdapter("E-mail login requires an adapter.")
}
const missingMethods = [
"createVerificationToken",
"useVerificationToken",
"getUserByEmail",
].filter((method) => !adapter[method])
const missingMethods = (
[
"createVerificationToken",
"useVerificationToken",
"getUserByEmail",
] as const
).filter((method) => !adapter[method])
if (missingMethods.length) {
return new MissingAdapterMethods(

View File

@@ -169,7 +169,7 @@ function eventsErrorHandler(
const method: Method = methods[name as keyof Method]
return await method(...args)
} catch (e) {
logger.error(new EventError(e))
logger.error(new EventError(e as Error))
}
}
return acc
@@ -190,7 +190,7 @@ function adapterErrorHandler<TAdapter>(
const method: Method = adapter[name as keyof Method]
return await method(...args)
} catch (e) {
const error = new AdapterError(e)
const error = new AdapterError(e as Error)
logger.error(error)
throw error
}

View File

@@ -187,7 +187,7 @@ async function getProfile(
},
OAuthProfile,
}
} catch (error) {
} catch (e) {
// If we didn't get a response either there was a problem with the provider
// response *or* the user cancelled the action with the provider.
//
@@ -196,6 +196,6 @@ async function getProfile(
// redirected back to the sign up page. We log the error to help developers
// who might be trying to debug this when configuring a new provider.
logger.debug("getProfile error details", OAuthProfile)
logger.error(new OAuthProfileParseError(error))
logger.error(new OAuthProfileParseError(e as Error))
}
}

View File

@@ -80,7 +80,7 @@ export default function ErrorPage(props: ErrorProps) {
}
const { status, heading, message, signin } =
errors[error.toLowerCase()] ?? errors.default
errors[error.toLowerCase() as Lowercase<ErrorPageParam>] ?? errors.default
return {
status,

View File

@@ -48,7 +48,9 @@ export default function SigninPage(props: {
}
const error =
errorType && (signinErrors[errorType.toLowerCase()] ?? signinErrors.default)
errorType &&
(signinErrors[errorType.toLowerCase() as Lowercase<SignInPageErrorParam>] ??
signinErrors.default)
// TODO: move logos
const logos =

View File

@@ -1,2 +1,296 @@
export default `:root{--border-width:1px;--border-radius:0.5rem;--color-error:#c94b4b;--color-info:#157efb;--color-info-text:#fff}.__next-auth-theme-auto,.__next-auth-theme-light{--color-background:#fff;--color-text:#000;--color-primary:#444;--color-control-border:#bbb;--color-button-active-background:#f9f9f9;--color-button-active-border:#aaa;--color-seperator:#ccc}.__next-auth-theme-dark{--color-background:#000;--color-text:#fff;--color-primary:#ccc;--color-control-border:#555;--color-button-active-background:#060606;--color-button-active-border:#666;--color-seperator:#444}@media (prefers-color-scheme:dark){.__next-auth-theme-auto{--color-background:#000;--color-text:#fff;--color-primary:#ccc;--color-control-border:#555;--color-button-active-background:#060606;--color-button-active-border:#666;--color-seperator:#444}}body{background-color:var(--color-background);font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;margin:0;padding:0}h1{font-weight:400;margin-bottom:1.5rem;padding:0 1rem}h1,p{color:var(--color-text)}form{margin:0;padding:0}label{font-weight:500;margin-bottom:.25rem;text-align:left}input[type],label{color:var(--color-text);display:block}input[type]{background:var(--color-background);border:var(--border-width) solid var(--color-control-border);border-radius:var(--border-radius);box-shadow:inset 0 .1rem .2rem rgba(0,0,0,.2);box-sizing:border-box;font-size:1rem;padding:.5rem 1rem;width:100%}input[type]:focus{box-shadow:none}p{font-size:1.1rem;line-height:2rem;margin:0 0 1.5rem;padding:0 1rem}a.button{line-height:1rem;text-decoration:none}a.button:link,a.button:visited{background-color:var(--color-background);color:var(--color-primary)}a.button,button{align-items:center;background-color:var(--provider-bg,var(--color-background));border-color:rgba(0,0,0,.1);border-radius:var(--border-radius);box-shadow:0 0 0 0 #000,0 0 0 0 #000,0 10px 15px -3px rgba(0,0,0,.2),0 4px 6px -4px rgba(0,0,0,.1);color:var(--provider-color,var(--color-primary));display:flex;font-size:1.1rem;font-weight:500;justify-content:center;margin:0 0 .75rem;min-height:62px;padding:.75rem 1rem;position:relative;transition:all .1s ease-in-out}a.button:has(img),button:has(img){justify-content:unset}a.button:has(img) span,button:has(img) span{flex-grow:1}a.button:hover,button:hover{cursor:pointer}a.button:active,button:active{box-shadow:0 .15rem .3rem rgba(0,0,0,.15),inset 0 .1rem .2rem var(--color-background),inset 0 -.1rem .1rem rgba(0,0,0,.1);cursor:pointer}a.button #provider-logo,button #provider-logo{display:block}a.button #provider-logo-dark,button #provider-logo-dark{display:none}@media (prefers-color-scheme:dark){a.button,button{background-color:var(--provider-dark-bg,var(--color-background));border:1px solid #0d0d0d;box-shadow:0 0 0 0 #000,0 0 0 0 #ccc,0 5px 5px -3px hsla(0,0%,100%,.01),0 4px 6px -4px hsla(0,0%,100%,.05);color:var(--provider-dark-color,var(--color-primary))}#provider-logo{display:none!important}#provider-logo-dark{display:block!important}}a.site{color:var(--color-primary);font-size:1rem;line-height:2rem;text-decoration:none}a.site:hover{text-decoration:underline}.page{display:grid;height:100%;margin:0;padding:0;place-items:center;position:absolute;width:100%}.page>div{padding:.5rem;text-align:center}.error a.button{display:inline-block;margin-top:.5rem;padding-left:2rem;padding-right:2rem}.error .message{margin-bottom:1.5rem}.signin input[type=text]{display:block;margin-left:auto;margin-right:auto}.signin hr{border:0;border-top:1px solid var(--color-seperator);display:block;margin:1.5em auto 0;overflow:visible}.signin hr:before{background:var(--color-background);color:#888;content:"or";padding:0 .4rem;position:relative;top:-.6rem}.signin .error{background:#f5f5f5;background:var(--color-info);border-radius:.3rem;font-weight:500}.signin .error p{color:var(--color-info-text);font-size:.9rem;line-height:1.2rem;padding:.5rem 1rem;text-align:left}.signin form,.signin>div{display:block}.signin form input[type],.signin>div input[type]{margin-bottom:.5rem}.signin form button,.signin>div button{width:100%}.signin form,.signin>div{max-width:300px}.signout .message{margin-bottom:1.5rem}.logo{display:inline-block;margin-top:100px;max-height:150px;max-width:300px}.card{border:1px solid var(--color-control-border);border-radius:5px;margin:50px auto;max-width:-moz-max-content;max-width:max-content;padding:20px 50px}.card .header{color:var(--color-primary)}.section-header{color:var(--brand-color,var(--color-text))}`
export default `:root {
--border-width: 1px;
--border-radius: 0.5rem;
--color-error: #c94b4b;
--color-info: #157efb;
--color-info-text: #fff;
}
.__next-auth-theme-auto,
.__next-auth-theme-light {
--color-background: #fff;
--color-text: #000;
--color-primary: #444;
--color-control-border: #bbb;
--color-button-active-background: #f9f9f9;
--color-button-active-border: #aaa;
--color-seperator: #ccc;
}
.__next-auth-theme-dark {
--color-background: #000;
--color-text: #fff;
--color-primary: #ccc;
--color-control-border: #555;
--color-button-active-background: #060606;
--color-button-active-border: #666;
--color-seperator: #444;
}
@media (prefers-color-scheme: dark) {
.__next-auth-theme-auto {
--color-background: #000;
--color-text: #fff;
--color-primary: #ccc;
--color-control-border: #555;
--color-button-active-background: #060606;
--color-button-active-border: #666;
--color-seperator: #444;
}
}
body {
background-color: var(--color-background);
margin: 0;
padding: 0;
font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont,
"Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif,
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
h1 {
font-weight: 400;
margin-bottom: 1.5rem;
padding: 0 1rem;
color: var(--color-text);
}
p {
color: var(--color-text);
}
form {
margin: 0;
padding: 0;
}
label {
font-weight: 500;
text-align: left;
margin-bottom: 0.25rem;
display: block;
color: var(--color-text);
}
input[type] {
box-sizing: border-box;
display: block;
width: 100%;
padding: 0.5rem 1rem;
border: var(--border-width) solid var(--color-control-border);
background: var(--color-background);
font-size: 1rem;
border-radius: var(--border-radius);
box-shadow: inset 0 0.1rem 0.2rem rgba(0, 0, 0, 0.2);
color: var(--color-text);
}
input[type]:focus {
box-shadow: none;
}
p {
margin: 0 0 1.5rem 0;
padding: 0 1rem;
font-size: 1.1rem;
line-height: 2rem;
}
a.button {
text-decoration: none;
line-height: 1rem;
}
a.button:link,
a.button:visited {
background-color: var(--color-background);
color: var(--color-primary);
}
button,
a.button {
margin: 0 0 0.75rem 0;
padding: 0.75rem 1rem;
color: var(--provider-color, var(--color-primary));
background-color: var(--provider-bg, var(--color-background));
font-size: 1.1rem;
min-height: 62px;
border-color: rgba(0, 0, 0, 0.1);
border-radius: var(--border-radius);
transition: all 0.1s ease-in-out;
box-shadow: #000 0px 0px 0px 0px, #000 0px 0px 0px 0px,
rgba(0, 0, 0, 0.2) 0px 10px 15px -3px, rgba(0, 0, 0, 0.1) 0px 4px 6px -4px;
font-weight: 500;
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
button:has(img), a.button:has(img) {
justify-content: unset;
}
button:has(img) span, a.button:has(img) span {
flex-grow: 1;
}
button:hover, a.button:hover {
cursor: pointer;
}
button:active, a.button:active {
box-shadow: 0 0.15rem 0.3rem rgba(0, 0, 0, 0.15),
inset 0 0.1rem 0.2rem var(--color-background),
inset 0 -0.1rem 0.1rem rgba(0, 0, 0, 0.1);
cursor: pointer;
}
button #provider-logo, a.button #provider-logo {
display: block;
}
button #provider-logo-dark, a.button #provider-logo-dark {
display: none;
}
@media (prefers-color-scheme: dark) {
button,
a.button {
color: var(--provider-dark-color, var(--color-primary));
background-color: var(--provider-dark-bg, var(--color-background));
border: 1px solid #0d0d0d;
box-shadow: #000 0px 0px 0px 0px, #ccc 0px 0px 0px 0px,
rgba(255, 255, 255, 0.01) 0px 5px 5px -3px,
rgba(255, 255, 255, 0.05) 0px 4px 6px -4px;
}
#provider-logo {
display: none !important;
}
#provider-logo-dark {
display: block !important;
}
}
a.site {
color: var(--color-primary);
text-decoration: none;
font-size: 1rem;
line-height: 2rem;
}
a.site:hover {
text-decoration: underline;
}
.page {
position: absolute;
width: 100%;
height: 100%;
display: grid;
place-items: center;
margin: 0;
padding: 0;
}
.page > div {
text-align: center;
padding: 0.5rem;
}
.error a.button {
display: inline-block;
padding-left: 2rem;
padding-right: 2rem;
margin-top: 0.5rem;
}
.error .message {
margin-bottom: 1.5rem;
}
.signin input[type="text"] {
margin-left: auto;
margin-right: auto;
display: block;
}
.signin hr {
display: block;
border: 0;
border-top: 1px solid var(--color-seperator);
margin: 1.5em auto 0 auto;
overflow: visible;
}
.signin hr::before {
content: "or";
background: var(--color-background);
color: #888;
padding: 0 0.4rem;
position: relative;
top: -0.6rem;
}
.signin .error {
background: #f5f5f5;
font-weight: 500;
border-radius: 0.3rem;
background: var(--color-info);
}
.signin .error p {
text-align: left;
padding: 0.5rem 1rem;
font-size: 0.9rem;
line-height: 1.2rem;
color: var(--color-info-text);
}
.signin > div,
.signin form {
display: block;
}
.signin > div input[type], .signin form input[type] {
margin-bottom: 0.5rem;
}
.signin > div button, .signin form button {
width: 100%;
}
.signin > div,
.signin form {
max-width: 300px;
}
.signout .message {
margin-bottom: 1.5rem;
}
.logo {
display: inline-block;
margin-top: 100px;
max-width: 300px;
max-height: 150px;
}
.card {
max-width: -moz-max-content;
max-width: max-content;
border: 1px solid var(--color-control-border);
border-radius: 5px;
padding: 20px 50px;
margin: 50px auto;
}
.card .header {
color: var(--color-primary);
}
.section-header {
color: var(--brand-color, var(--color-text));
}
`
// Generated by `pnpm css`

View File

@@ -97,5 +97,5 @@ function normalizeEndpoint(
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
for (const k in e.params) url.searchParams.set(k, e.params[k] as any)
return { url }
return { ...e, url }
}

View File

@@ -273,11 +273,11 @@ export async function callback(params: {
cookies,
}
}
} catch (error) {
} catch (e) {
return {
status: 401,
redirect: `${url}/error?error=${encodeURIComponent(
(error as Error).message
(e as Error).message
)}`,
cookies,
}
@@ -337,7 +337,7 @@ export async function callback(params: {
cookies,
}
} catch (e) {
const error = new CallbackRouteError(e, { provider: provider.id })
const error = new CallbackRouteError(e as Error, { provider: provider.id })
logger.error(error)
url.searchParams.set("error", CallbackRouteError.name)

View File

@@ -69,8 +69,8 @@ export async function session(
response.cookies?.push(...sessionCookies)
await events.session?.({ session: newSession, token })
} catch (error) {
logger.error(new JWTSessionError(error))
} catch (e) {
logger.error(new JWTSessionError(e as Error))
// If the JWT is not verifiable remove the broken session cookie(s).
response.cookies?.push(...sessionStore.clean())
}
@@ -151,8 +151,8 @@ export async function session(
// remove the sessionToken cookie from browser.
response.cookies?.push(...sessionStore.clean())
}
} catch (error) {
logger.error(new SessionTokenError(error))
} catch (e) {
logger.error(new SessionTokenError(e as Error))
}
return response

View File

@@ -16,7 +16,7 @@ export async function handleAuthorized(
return { status: 403 as const, redirect: url }
}
} catch (e) {
const error = new AuthorizedCallbackError(e)
const error = new AuthorizedCallbackError(e as Error)
logger.error(error)
url.searchParams.set("error", "Configuration")
return { status: 500 as const, redirect: url }

View File

@@ -50,7 +50,7 @@ export async function signin(
}
return { redirect: `${url}/signin` }
} catch (e) {
const error = new SignInError(e, { provider: provider.id })
const error = new SignInError(e as Error, { provider: provider.id })
logger.error(error)
url.searchParams.set("error", error.name)
url.pathname += "/error"

View File

@@ -27,8 +27,8 @@ export async function signout(
const session = await options.adapter?.deleteSession(sessionToken)
await events.signOut?.({ session })
}
} catch (error) {
logger.error(new SignOutError(error))
} catch (e) {
logger.error(new SignOutError(e as Error))
}
return { redirect, cookies: sessionStore.clean() }

View File

@@ -65,8 +65,8 @@ export async function toInternalRequest(
error: url.searchParams.get("error") ?? undefined,
query: Object.fromEntries(url.searchParams),
}
} catch (error) {
return error
} catch (e) {
return e as Error
}
}
@@ -102,7 +102,7 @@ export function toResponse(res: ResponseInternal): Response {
}
/** Web compatible method to create a hash, using SHA256 */
export async function createHash(message) {
export async function createHash(message: string) {
const data = new TextEncoder().encode(message)
const hash = await crypto.subtle.digest("SHA-256", data)
return Array.from(new Uint8Array(hash))

View File

@@ -2,6 +2,7 @@ import type { OAuthConfig, OAuthUserConfig } from "./index.js"
export type DateTime = string
export type Gender = "female" | "male"
export type Birthday = "SOLAR" | "LUNAR"
export type AgeRange =
| "1-9"
| "10-14"
@@ -55,7 +56,7 @@ export interface KakaoProfile extends Record<string, any> {
birthyear?: string
birthday_needs_agreement?: boolean
birthday?: string
birthday_type?: string
birthday_type?: Birthday
gender_needs_agreement?: boolean
gender?: Gender
phone_number_needs_agreement?: boolean

View File

@@ -11,8 +11,6 @@ type OpenIDCallbackChecks = any
export type { OAuthProviderType } from "./oauth-types.js"
type ChecksType = "pkce" | "state" | "none" | "nonce"
export type OAuthChecks = OpenIDCallbackChecks | OAuthCallbackChecks
type PartialIssuer = Partial<Pick<IssuerMetadata, "jwks_endpoint" | "issuer">>
@@ -139,13 +137,13 @@ export interface OAuth2Config<P> extends CommonProviderOptions, PartialIssuer {
profile?: ProfileCallback<P>
/**
* The CSRF protection performed on the callback endpoint.
* Defaults to `["pkce"]` if undefined.
* @default ["pkce"]
*
* [RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients (PKCE)](https://www.rfc-editor.org/rfc/rfc7636.html#section-4) |
* [RFC 6749 - The OAuth 2.0 Authorization Framework](https://www.rfc-editor.org/rfc/rfc6749.html#section-4.1.1) |
* [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html#IDToken) |
*/
checks?: ChecksType[]
checks?: Array<"pkce" | "state" | "none" | "nonce">
clientId?: string
clientSecret?: string
client?: Partial<Client>
@@ -177,17 +175,11 @@ export type OAuthEndpointType = "authorization" | "token" | "userinfo"
* We parsesd `authorization`, `token` and `userinfo`
* to always contain a valid `URL`, with the params
*/
export type OAuthConfigInternal<P> = Omit<
OAuthConfig<P>,
OAuthEndpointType | "clientId" | "checks" | "profile"
> & {
clientId: string
export type OAuthConfigInternal<P> = Omit<OAuthConfig<P>, OAuthEndpointType> & {
authorization?: { url: URL }
token?: { url: URL; request?: TokenEndpointHandler["request"] }
userinfo?: { url: URL; request?: UserinfoEndpointHandler["request"] }
checks: ChecksType[]
profile: ProfileCallback<P>
}
} & Pick<Required<OAuthConfig<P>>, "clientId" | "checks" | "profile">
export type OAuthUserConfig<P> = Omit<
Partial<OAuthConfig<P>>,

View File

@@ -146,6 +146,7 @@ export default function Twitter<
id: "twitter",
name: "Twitter",
type: "oauth",
checks: ["pkce", "state"],
authorization: {
url: "https://twitter.com/i/oauth2/authorize",
params: { scope: "users.read tweet.read offline.access" },

View File

@@ -13,12 +13,11 @@
"outDir": ".",
"rootDir": "src",
"skipDefaultLibCheck": true,
"strict": false,
"strictNullChecks": true,
"stripInternal": true,
"declarationMap": true,
"declaration": true
},
"include": ["src/**/*"],
"exclude": ["adapters.*", "index.*", "jwt", "lib", "providers"]
"exclude": ["*.js", "*.d.ts", "lib", "providers"]
}

View File

@@ -1,7 +1,17 @@
{
"name": "@auth/sveltekit",
"version": "0.1.9",
"version": "0.1.10",
"description": "Authentication for SvelteKit.",
"keywords": [
"authentication",
"authjs",
"jwt",
"sveltekit",
"oauth",
"oidc",
"passwordless",
"svelte"
],
"homepage": "https://sveltekit.authjs.dev",
"repository": "https://github.com/nextauthjs/next-auth.git",
"author": "Thang Huu Vu <hi@thvu.dev>",
@@ -59,4 +69,4 @@
},
"./package.json": "./package.json"
}
}
}

View File

@@ -42,7 +42,7 @@
"clean": "rm -rf coverage client css utils providers core jwt react next index.d.ts index.js adapters.d.ts middleware.d.ts middleware.js",
"build:css": "postcss --config config/postcss.config.js src/**/*.css --base src --dir . && node config/wrap-css.js",
"dev": "pnpm clean && pnpm generate-providers && concurrently \"pnpm watch:css\" \"pnpm watch:ts\"",
"watch:ts": "pnpm tsc --project tsconfig.dev.json",
"watch:ts": "pnpm tsc",
"watch:css": "postcss --config config/postcss.config.js --watch src/**/*.css --base src --dir .",
"test": "jest --config ./config/jest.config.js",
"prepublishOnly": "pnpm build",
@@ -119,7 +119,7 @@
"jest-environment-jsdom": "^28.1.1",
"jest-watch-typeahead": "^1.1.0",
"msw": "^0.42.3",
"next": "13.0.6",
"next": "13.1.1",
"postcss": "^8.4.14",
"postcss-cli": "^9.1.0",
"postcss-nested": "^5.0.6",

View File

@@ -4,6 +4,7 @@
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"declaration": true,
"skipLibCheck": true
"skipLibCheck": true,
"strict": true
}
}

697
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,22 +5,7 @@
"dependsOn": ["^build"]
},
"next-auth#build": {
"dependsOn": ["^build"],
"outputs": [
"lib/**",
"css/**",
"jwt/**",
"react/**",
"next/**",
"client/**",
"providers/**",
"core/**",
"index.d.ts",
"index.js",
"adapters.d.ts",
"middleware.d.ts",
"middleware.js"
]
"dependsOn": ["^build"]
},
"clean": {
"cache": false