mirror of
https://github.com/SrIzan10/next-auth.git
synced 2026-05-01 10:55:20 +00:00
Compare commits
34 Commits
@auth/core
...
feat-kakao
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53f41d637a | ||
|
|
e910c90525 | ||
|
|
2004a377ea | ||
|
|
ae57199258 | ||
|
|
aad425fced | ||
|
|
8ef1010bb1 | ||
|
|
950ca3169a | ||
|
|
edbf0fc011 | ||
|
|
46bac818fe | ||
|
|
9e64eb0cdd | ||
|
|
955e379330 | ||
|
|
7be4461253 | ||
|
|
c2e06dc445 | ||
|
|
4dd70a5f6f | ||
|
|
98dbf56494 | ||
|
|
6b4644f7e7 | ||
|
|
bcf909b69e | ||
|
|
4dcdd21242 | ||
|
|
137d993a13 | ||
|
|
8dda662cd6 | ||
|
|
8a438bab32 | ||
|
|
4aaad03e9c | ||
|
|
4fa0d1fa2a | ||
|
|
c081773667 | ||
|
|
1ab0a2aed4 | ||
|
|
cac9816d32 | ||
|
|
65defc709e | ||
|
|
1601626d31 | ||
|
|
8c4f439279 | ||
|
|
f24c91b8ee | ||
|
|
ad72985460 | ||
|
|
f299954e9b | ||
|
|
f325f76c24 | ||
|
|
05d9f1cbee |
2
.github/actions/issue-validator/index.mjs
vendored
2
.github/actions/issue-validator/index.mjs
vendored
File diff suppressed because one or more lines are too long
3
.github/actions/issue-validator/licenses.txt
vendored
3
.github/actions/issue-validator/licenses.txt
vendored
@@ -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
|
||||
|
||||
|
||||
14
.github/actions/issue-validator/src/index.mjs
vendored
14
.github/actions/issue-validator/src/index.mjs
vendored
@@ -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(
|
||||
|
||||
2
.github/workflows/sync-examples.yml
vendored
2
.github/workflows/sync-examples.yml
vendored
@@ -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
|
||||
|
||||
@@ -23,6 +23,7 @@ build
|
||||
docs/docs/reference/03-core
|
||||
docs/docs/reference/04-sveltekit
|
||||
static
|
||||
docs/providers.json
|
||||
|
||||
# --------------- Packages ---------------
|
||||
|
||||
|
||||
@@ -12,5 +12,11 @@ module.exports = {
|
||||
],
|
||||
options: { printWidth: 150 },
|
||||
},
|
||||
{
|
||||
files: ["**/*package.json"],
|
||||
options: {
|
||||
trailingComma: "none",
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
2
apps/dev/.vscode/settings.json
vendored
2
apps/dev/.vscode/settings.json
vendored
@@ -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
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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 {}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 =
|
||||
|
||||
@@ -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`
|
||||
@@ -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 }
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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() }
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>>,
|
||||
|
||||
@@ -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" },
|
||||
|
||||
@@ -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"]
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"esModuleInterop": true,
|
||||
"declaration": true,
|
||||
"skipLibCheck": true
|
||||
"skipLibCheck": true,
|
||||
"strict": true
|
||||
}
|
||||
}
|
||||
|
||||
697
pnpm-lock.yaml
generated
697
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
17
turbo.json
17
turbo.json
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user