@robelest/convex-auth 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/bin.cjs +27733 -0
- package/dist/client/index.d.ts +49 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +283 -0
- package/dist/client/index.js.map +1 -0
- package/dist/component/_generated/api.d.ts +36 -0
- package/dist/component/_generated/api.d.ts.map +1 -0
- package/dist/component/_generated/api.js +31 -0
- package/dist/component/_generated/api.js.map +1 -0
- package/dist/component/_generated/component.d.ts +295 -0
- package/dist/component/_generated/component.d.ts.map +1 -0
- package/dist/component/_generated/component.js +11 -0
- package/dist/component/_generated/component.js.map +1 -0
- package/dist/component/_generated/dataModel.d.ts +46 -0
- package/dist/component/_generated/dataModel.d.ts.map +1 -0
- package/dist/component/_generated/dataModel.js +11 -0
- package/dist/component/_generated/dataModel.js.map +1 -0
- package/dist/component/_generated/server.d.ts +121 -0
- package/dist/component/_generated/server.d.ts.map +1 -0
- package/dist/component/_generated/server.js +78 -0
- package/dist/component/_generated/server.js.map +1 -0
- package/dist/component/convex.config.d.ts +3 -0
- package/dist/component/convex.config.d.ts.map +1 -0
- package/dist/component/convex.config.js +4 -0
- package/dist/component/convex.config.js.map +1 -0
- package/dist/component/index.d.ts +15 -0
- package/dist/component/index.d.ts.map +1 -0
- package/dist/component/index.js +13 -0
- package/dist/component/index.js.map +1 -0
- package/dist/component/public.d.ts +450 -0
- package/dist/component/public.d.ts.map +1 -0
- package/dist/component/public.js +528 -0
- package/dist/component/public.js.map +1 -0
- package/dist/component/schema.d.ts +107 -0
- package/dist/component/schema.d.ts.map +1 -0
- package/dist/component/schema.js +26 -0
- package/dist/component/schema.js.map +1 -0
- package/dist/providers/Anonymous.d.ts +50 -0
- package/dist/providers/Anonymous.d.ts.map +1 -0
- package/dist/providers/Anonymous.js +39 -0
- package/dist/providers/Anonymous.js.map +1 -0
- package/dist/providers/ConvexCredentials.d.ts +88 -0
- package/dist/providers/ConvexCredentials.d.ts.map +1 -0
- package/dist/providers/ConvexCredentials.js +37 -0
- package/dist/providers/ConvexCredentials.js.map +1 -0
- package/dist/providers/Email.d.ts +33 -0
- package/dist/providers/Email.d.ts.map +1 -0
- package/dist/providers/Email.js +50 -0
- package/dist/providers/Email.js.map +1 -0
- package/dist/providers/Password.d.ts +95 -0
- package/dist/providers/Password.d.ts.map +1 -0
- package/dist/providers/Password.js +174 -0
- package/dist/providers/Password.js.map +1 -0
- package/dist/providers/Phone.d.ts +22 -0
- package/dist/providers/Phone.d.ts.map +1 -0
- package/dist/providers/Phone.js +37 -0
- package/dist/providers/Phone.js.map +1 -0
- package/dist/server/convex_types.d.ts +17 -0
- package/dist/server/convex_types.d.ts.map +1 -0
- package/dist/server/convex_types.js +2 -0
- package/dist/server/convex_types.js.map +1 -0
- package/dist/server/cookies.d.ts +35 -0
- package/dist/server/cookies.d.ts.map +1 -0
- package/dist/server/cookies.js +34 -0
- package/dist/server/cookies.js.map +1 -0
- package/dist/server/implementation/db.d.ts +80 -0
- package/dist/server/implementation/db.d.ts.map +1 -0
- package/dist/server/implementation/db.js +59 -0
- package/dist/server/implementation/db.js.map +1 -0
- package/dist/server/implementation/index.d.ts +370 -0
- package/dist/server/implementation/index.d.ts.map +1 -0
- package/dist/server/implementation/index.js +521 -0
- package/dist/server/implementation/index.js.map +1 -0
- package/dist/server/implementation/mutations/createAccountFromCredentials.d.ts +33 -0
- package/dist/server/implementation/mutations/createAccountFromCredentials.d.ts.map +1 -0
- package/dist/server/implementation/mutations/createAccountFromCredentials.js +71 -0
- package/dist/server/implementation/mutations/createAccountFromCredentials.js.map +1 -0
- package/dist/server/implementation/mutations/createVerificationCode.d.ts +25 -0
- package/dist/server/implementation/mutations/createVerificationCode.d.ts.map +1 -0
- package/dist/server/implementation/mutations/createVerificationCode.js +84 -0
- package/dist/server/implementation/mutations/createVerificationCode.js.map +1 -0
- package/dist/server/implementation/mutations/index.d.ts +304 -0
- package/dist/server/implementation/mutations/index.d.ts.map +1 -0
- package/dist/server/implementation/mutations/index.js +108 -0
- package/dist/server/implementation/mutations/index.js.map +1 -0
- package/dist/server/implementation/mutations/invalidateSessions.d.ts +13 -0
- package/dist/server/implementation/mutations/invalidateSessions.d.ts.map +1 -0
- package/dist/server/implementation/mutations/invalidateSessions.js +35 -0
- package/dist/server/implementation/mutations/invalidateSessions.js.map +1 -0
- package/dist/server/implementation/mutations/modifyAccount.d.ts +23 -0
- package/dist/server/implementation/mutations/modifyAccount.d.ts.map +1 -0
- package/dist/server/implementation/mutations/modifyAccount.js +48 -0
- package/dist/server/implementation/mutations/modifyAccount.js.map +1 -0
- package/dist/server/implementation/mutations/refreshSession.d.ts +16 -0
- package/dist/server/implementation/mutations/refreshSession.d.ts.map +1 -0
- package/dist/server/implementation/mutations/refreshSession.js +116 -0
- package/dist/server/implementation/mutations/refreshSession.js.map +1 -0
- package/dist/server/implementation/mutations/retrieveAccountWithCredentials.d.ts +27 -0
- package/dist/server/implementation/mutations/retrieveAccountWithCredentials.d.ts.map +1 -0
- package/dist/server/implementation/mutations/retrieveAccountWithCredentials.js +55 -0
- package/dist/server/implementation/mutations/retrieveAccountWithCredentials.js.map +1 -0
- package/dist/server/implementation/mutations/signIn.d.ts +17 -0
- package/dist/server/implementation/mutations/signIn.d.ts.map +1 -0
- package/dist/server/implementation/mutations/signIn.js +26 -0
- package/dist/server/implementation/mutations/signIn.js.map +1 -0
- package/dist/server/implementation/mutations/signOut.d.ts +11 -0
- package/dist/server/implementation/mutations/signOut.d.ts.map +1 -0
- package/dist/server/implementation/mutations/signOut.js +24 -0
- package/dist/server/implementation/mutations/signOut.js.map +1 -0
- package/dist/server/implementation/mutations/userOAuth.d.ts +19 -0
- package/dist/server/implementation/mutations/userOAuth.d.ts.map +1 -0
- package/dist/server/implementation/mutations/userOAuth.js +84 -0
- package/dist/server/implementation/mutations/userOAuth.js.map +1 -0
- package/dist/server/implementation/mutations/verifier.d.ts +8 -0
- package/dist/server/implementation/mutations/verifier.d.ts.map +1 -0
- package/dist/server/implementation/mutations/verifier.js +19 -0
- package/dist/server/implementation/mutations/verifier.js.map +1 -0
- package/dist/server/implementation/mutations/verifierSignature.d.ts +15 -0
- package/dist/server/implementation/mutations/verifierSignature.d.ts.map +1 -0
- package/dist/server/implementation/mutations/verifierSignature.js +29 -0
- package/dist/server/implementation/mutations/verifierSignature.js.map +1 -0
- package/dist/server/implementation/mutations/verifyCodeAndSignIn.d.ts +21 -0
- package/dist/server/implementation/mutations/verifyCodeAndSignIn.d.ts.map +1 -0
- package/dist/server/implementation/mutations/verifyCodeAndSignIn.js +127 -0
- package/dist/server/implementation/mutations/verifyCodeAndSignIn.js.map +1 -0
- package/dist/server/implementation/provider.d.ts +6 -0
- package/dist/server/implementation/provider.d.ts.map +1 -0
- package/dist/server/implementation/provider.js +21 -0
- package/dist/server/implementation/provider.js.map +1 -0
- package/dist/server/implementation/rateLimit.d.ts +6 -0
- package/dist/server/implementation/rateLimit.d.ts.map +1 -0
- package/dist/server/implementation/rateLimit.js +76 -0
- package/dist/server/implementation/rateLimit.js.map +1 -0
- package/dist/server/implementation/redirects.d.ts +6 -0
- package/dist/server/implementation/redirects.d.ts.map +1 -0
- package/dist/server/implementation/redirects.js +40 -0
- package/dist/server/implementation/redirects.js.map +1 -0
- package/dist/server/implementation/refreshTokens.d.ts +40 -0
- package/dist/server/implementation/refreshTokens.d.ts.map +1 -0
- package/dist/server/implementation/refreshTokens.js +160 -0
- package/dist/server/implementation/refreshTokens.js.map +1 -0
- package/dist/server/implementation/sessions.d.ts +43 -0
- package/dist/server/implementation/sessions.d.ts.map +1 -0
- package/dist/server/implementation/sessions.js +94 -0
- package/dist/server/implementation/sessions.js.map +1 -0
- package/dist/server/implementation/signIn.d.ts +31 -0
- package/dist/server/implementation/signIn.d.ts.map +1 -0
- package/dist/server/implementation/signIn.js +148 -0
- package/dist/server/implementation/signIn.js.map +1 -0
- package/dist/server/implementation/tokens.d.ts +7 -0
- package/dist/server/implementation/tokens.d.ts.map +1 -0
- package/dist/server/implementation/tokens.js +18 -0
- package/dist/server/implementation/tokens.js.map +1 -0
- package/dist/server/implementation/types.d.ts +288 -0
- package/dist/server/implementation/types.d.ts.map +1 -0
- package/dist/server/implementation/types.js +182 -0
- package/dist/server/implementation/types.js.map +1 -0
- package/dist/server/implementation/users.d.ts +27 -0
- package/dist/server/implementation/users.d.ts.map +1 -0
- package/dist/server/implementation/users.js +181 -0
- package/dist/server/implementation/users.js.map +1 -0
- package/dist/server/implementation/utils.d.ts +17 -0
- package/dist/server/implementation/utils.d.ts.map +1 -0
- package/dist/server/implementation/utils.js +72 -0
- package/dist/server/implementation/utils.js.map +1 -0
- package/dist/server/index.d.ts +17 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +54 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/oauth/authorizationUrl.d.ts +13 -0
- package/dist/server/oauth/authorizationUrl.d.ts.map +1 -0
- package/dist/server/oauth/authorizationUrl.js +91 -0
- package/dist/server/oauth/authorizationUrl.js.map +1 -0
- package/dist/server/oauth/callback.d.ts +19 -0
- package/dist/server/oauth/callback.d.ts.map +1 -0
- package/dist/server/oauth/callback.js +173 -0
- package/dist/server/oauth/callback.js.map +1 -0
- package/dist/server/oauth/checks.d.ts +52 -0
- package/dist/server/oauth/checks.d.ts.map +1 -0
- package/dist/server/oauth/checks.js +106 -0
- package/dist/server/oauth/checks.js.map +1 -0
- package/dist/server/oauth/convexAuth.d.ts +12 -0
- package/dist/server/oauth/convexAuth.d.ts.map +1 -0
- package/dist/server/oauth/convexAuth.js +137 -0
- package/dist/server/oauth/convexAuth.js.map +1 -0
- package/dist/server/oauth/lib/utils/customFetch.d.ts +9 -0
- package/dist/server/oauth/lib/utils/customFetch.d.ts.map +1 -0
- package/dist/server/oauth/lib/utils/customFetch.js +11 -0
- package/dist/server/oauth/lib/utils/customFetch.js.map +1 -0
- package/dist/server/oauth/lib/utils/providers.d.ts +3 -0
- package/dist/server/oauth/lib/utils/providers.d.ts.map +1 -0
- package/dist/server/oauth/lib/utils/providers.js +7 -0
- package/dist/server/oauth/lib/utils/providers.js.map +1 -0
- package/dist/server/oauth/providers/oauth.d.ts +43 -0
- package/dist/server/oauth/providers/oauth.d.ts.map +1 -0
- package/dist/server/oauth/providers/oauth.js +3 -0
- package/dist/server/oauth/providers/oauth.js.map +1 -0
- package/dist/server/oauth/types.d.ts +24 -0
- package/dist/server/oauth/types.d.ts.map +1 -0
- package/dist/server/oauth/types.js +5 -0
- package/dist/server/oauth/types.js.map +1 -0
- package/dist/server/provider_utils.d.ts +76 -0
- package/dist/server/provider_utils.d.ts.map +1 -0
- package/dist/server/provider_utils.js +177 -0
- package/dist/server/provider_utils.js.map +1 -0
- package/dist/server/types.d.ts +412 -0
- package/dist/server/types.d.ts.map +1 -0
- package/dist/server/types.js +2 -0
- package/dist/server/types.js.map +1 -0
- package/dist/server/utils.d.ts +3 -0
- package/dist/server/utils.d.ts.map +1 -0
- package/dist/server/utils.js +11 -0
- package/dist/server/utils.js.map +1 -0
- package/package.json +126 -0
- package/providers/Anonymous/package.json +6 -0
- package/providers/ConvexCredentials/package.json +6 -0
- package/providers/Email/package.json +6 -0
- package/providers/Password/package.json +6 -0
- package/providers/Phone/package.json +6 -0
- package/server/package.json +6 -0
- package/src/cli/command.ts +69 -0
- package/src/cli/generateKeys.ts +20 -0
- package/src/cli/index.ts +840 -0
- package/src/client/index.ts +415 -0
- package/src/component/_generated/api.ts +52 -0
- package/src/component/_generated/component.ts +586 -0
- package/src/component/_generated/dataModel.ts +60 -0
- package/src/component/_generated/server.ts +156 -0
- package/src/component/convex.config.ts +5 -0
- package/src/component/index.ts +40 -0
- package/src/component/public.ts +607 -0
- package/src/component/schema.ts +35 -0
- package/src/providers/Anonymous.ts +79 -0
- package/src/providers/ConvexCredentials.ts +108 -0
- package/src/providers/Email.ts +60 -0
- package/src/providers/Password.ts +253 -0
- package/src/providers/Phone.ts +46 -0
- package/src/server/convex_types.ts +55 -0
- package/src/server/cookies.ts +42 -0
- package/src/server/implementation/db.ts +125 -0
- package/src/server/implementation/index.ts +815 -0
- package/src/server/implementation/mutations/createAccountFromCredentials.ts +113 -0
- package/src/server/implementation/mutations/createVerificationCode.ts +139 -0
- package/src/server/implementation/mutations/index.ts +157 -0
- package/src/server/implementation/mutations/invalidateSessions.ts +47 -0
- package/src/server/implementation/mutations/modifyAccount.ts +65 -0
- package/src/server/implementation/mutations/refreshSession.ts +188 -0
- package/src/server/implementation/mutations/retrieveAccountWithCredentials.ts +87 -0
- package/src/server/implementation/mutations/signIn.ts +51 -0
- package/src/server/implementation/mutations/signOut.ts +38 -0
- package/src/server/implementation/mutations/userOAuth.ts +112 -0
- package/src/server/implementation/mutations/verifier.ts +29 -0
- package/src/server/implementation/mutations/verifierSignature.ts +44 -0
- package/src/server/implementation/mutations/verifyCodeAndSignIn.ts +205 -0
- package/src/server/implementation/provider.ts +38 -0
- package/src/server/implementation/rateLimit.ts +105 -0
- package/src/server/implementation/redirects.ts +58 -0
- package/src/server/implementation/refreshTokens.ts +221 -0
- package/src/server/implementation/sessions.ts +155 -0
- package/src/server/implementation/signIn.ts +253 -0
- package/src/server/implementation/tokens.ts +29 -0
- package/src/server/implementation/types.ts +220 -0
- package/src/server/implementation/users.ts +286 -0
- package/src/server/implementation/utils.ts +91 -0
- package/src/server/index.ts +74 -0
- package/src/server/oauth/NOTICE.txt +21 -0
- package/src/server/oauth/README.md +7 -0
- package/src/server/oauth/authorizationUrl.ts +113 -0
- package/src/server/oauth/callback.ts +243 -0
- package/src/server/oauth/checks.ts +136 -0
- package/src/server/oauth/convexAuth.ts +168 -0
- package/src/server/oauth/lib/utils/customFetch.ts +18 -0
- package/src/server/oauth/lib/utils/providers.ts +12 -0
- package/src/server/oauth/providers/oauth.ts +56 -0
- package/src/server/oauth/types.ts +60 -0
- package/src/server/provider_utils.ts +222 -0
- package/src/server/types.ts +470 -0
- package/src/server/utils.ts +12 -0
- package/src/test.ts +24 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
// This maps to packages/core/src/lib/actions/callback/oauth/callback.ts in the @auth/core package (commit 5af1f30a32e64591abc50ae4d2dba4682e525431)
|
|
2
|
+
|
|
3
|
+
import * as checks from "./checks.js";
|
|
4
|
+
import * as o from "oauth4webapi";
|
|
5
|
+
import { InternalOptions } from "./types.js";
|
|
6
|
+
import { fetchOpt } from "./lib/utils/customFetch.js";
|
|
7
|
+
import { Cookie } from "@auth/core/lib/utils/cookie.js";
|
|
8
|
+
import { logWithLevel } from "../implementation/utils.js";
|
|
9
|
+
import { Account, Profile, TokenSet } from "@auth/core/types.js";
|
|
10
|
+
import { isOIDCProvider } from "./lib/utils/providers.js";
|
|
11
|
+
import {
|
|
12
|
+
callbackUrl,
|
|
13
|
+
getAuthorizationSignature,
|
|
14
|
+
} from "./convexAuth.js";
|
|
15
|
+
|
|
16
|
+
function formUrlEncode(token: string) {
|
|
17
|
+
return encodeURIComponent(token).replace(/%20/g, "+");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Formats client_id and client_secret as an HTTP Basic Authentication header as per the OAuth 2.0
|
|
22
|
+
* specified in RFC6749.
|
|
23
|
+
*/
|
|
24
|
+
function clientSecretBasic(clientId: string, clientSecret: string) {
|
|
25
|
+
const username = formUrlEncode(clientId);
|
|
26
|
+
const password = formUrlEncode(clientSecret);
|
|
27
|
+
const credentials = btoa(`${username}:${password}`);
|
|
28
|
+
return `Basic ${credentials}`;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Handles the following OAuth steps.
|
|
33
|
+
* https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
|
|
34
|
+
* https://www.rfc-editor.org/rfc/rfc6749#section-4.1.3
|
|
35
|
+
* https://openid.net/specs/openid-connect-core-1_0.html#UserInfoRequest
|
|
36
|
+
*
|
|
37
|
+
* @note Although requesting userinfo is not required by the OAuth2.0 spec,
|
|
38
|
+
* we fetch it anyway. This is because we always want a user profile.
|
|
39
|
+
*/
|
|
40
|
+
export async function handleOAuth(
|
|
41
|
+
// ConvexAuth: `params` is a Record<string, string> instead of RequestInternal["query"]
|
|
42
|
+
params: Record<string, string>,
|
|
43
|
+
// ConvexAuth: `cookies` is a Record<string, string | undefined> instead of RequestInternal["cookies"]
|
|
44
|
+
cookies: Record<string, string | undefined>,
|
|
45
|
+
options: InternalOptions<"oauth" | "oidc">,
|
|
46
|
+
): Promise<{
|
|
47
|
+
profile: Profile,
|
|
48
|
+
tokens: TokenSet & Pick<Account, "expires_at">,
|
|
49
|
+
cookies: Cookie[],
|
|
50
|
+
signature: string,
|
|
51
|
+
}> {
|
|
52
|
+
const { provider } = options;
|
|
53
|
+
|
|
54
|
+
// ConvexAuth: The `token` property is not used here
|
|
55
|
+
const { userinfo, as } = provider;
|
|
56
|
+
|
|
57
|
+
const client: o.Client = {
|
|
58
|
+
client_id: provider.clientId,
|
|
59
|
+
...provider.client,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
let clientAuth: o.ClientAuth;
|
|
63
|
+
|
|
64
|
+
switch (client.token_endpoint_auth_method) {
|
|
65
|
+
// TODO: in the next breaking major version have undefined be `client_secret_post`
|
|
66
|
+
case undefined:
|
|
67
|
+
case "client_secret_basic":
|
|
68
|
+
// TODO: in the next breaking major version use o.ClientSecretBasic() here
|
|
69
|
+
clientAuth = (_as, _client, _body, headers) => {
|
|
70
|
+
headers.set(
|
|
71
|
+
"authorization",
|
|
72
|
+
clientSecretBasic(provider.clientId, provider.clientSecret!),
|
|
73
|
+
);
|
|
74
|
+
};
|
|
75
|
+
break;
|
|
76
|
+
case "client_secret_post":
|
|
77
|
+
clientAuth = o.ClientSecretPost(provider.clientSecret!);
|
|
78
|
+
break;
|
|
79
|
+
case "client_secret_jwt":
|
|
80
|
+
clientAuth = o.ClientSecretJwt(provider.clientSecret!);
|
|
81
|
+
break;
|
|
82
|
+
case "private_key_jwt":
|
|
83
|
+
clientAuth = o.PrivateKeyJwt(provider.token!.clientPrivateKey!, {
|
|
84
|
+
// TODO: review in the next breaking change
|
|
85
|
+
[o.modifyAssertion](_header, payload) {
|
|
86
|
+
payload.aud = [as.issuer, as.token_endpoint!];
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
break;
|
|
90
|
+
default:
|
|
91
|
+
throw new Error("unsupported client authentication method");
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const resCookies: Cookie[] = [];
|
|
95
|
+
|
|
96
|
+
const state = await checks.state.use(cookies, resCookies, options);
|
|
97
|
+
|
|
98
|
+
let codeGrantParams: URLSearchParams;
|
|
99
|
+
try {
|
|
100
|
+
codeGrantParams = o.validateAuthResponse(
|
|
101
|
+
as,
|
|
102
|
+
client,
|
|
103
|
+
new URLSearchParams(params),
|
|
104
|
+
provider.checks.includes("state") ? state : o.skipStateCheck,
|
|
105
|
+
);
|
|
106
|
+
} catch (err) {
|
|
107
|
+
if (err instanceof o.AuthorizationResponseError) {
|
|
108
|
+
const cause = {
|
|
109
|
+
providerId: provider.id,
|
|
110
|
+
...Object.fromEntries(err.cause.entries()),
|
|
111
|
+
};
|
|
112
|
+
logWithLevel("DEBUG", "OAuthCallbackError", cause);
|
|
113
|
+
throw new Error("OAuth Provider returned an error", { cause });
|
|
114
|
+
}
|
|
115
|
+
throw err;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const codeVerifier = await checks.pkce.use(cookies, resCookies, options);
|
|
119
|
+
|
|
120
|
+
// ConvexAuth: The logic for the callback URL is different from Auth.js
|
|
121
|
+
const redirect_uri = callbackUrl(provider.id);
|
|
122
|
+
// TODO(ConvexAuth): Support redirect proxy URLs
|
|
123
|
+
// if (!options.isOnRedirectProxy && provider.redirectProxyUrl) {
|
|
124
|
+
// redirect_uri = provider.redirectProxyUrl;
|
|
125
|
+
// }
|
|
126
|
+
|
|
127
|
+
let codeGrantResponse = await o.authorizationCodeGrantRequest(
|
|
128
|
+
as,
|
|
129
|
+
client,
|
|
130
|
+
clientAuth,
|
|
131
|
+
codeGrantParams,
|
|
132
|
+
redirect_uri,
|
|
133
|
+
codeVerifier ?? "decoy",
|
|
134
|
+
{
|
|
135
|
+
// TODO: move away from allowing insecure HTTP requests
|
|
136
|
+
[o.allowInsecureRequests]: true,
|
|
137
|
+
[o.customFetch]: (...args) => {
|
|
138
|
+
if (!provider.checks.includes("pkce")) {
|
|
139
|
+
args[1].body.delete("code_verifier");
|
|
140
|
+
}
|
|
141
|
+
return fetchOpt(provider)[o.customFetch](...args);
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
if (provider.token?.conform) {
|
|
147
|
+
codeGrantResponse =
|
|
148
|
+
(await provider.token.conform(codeGrantResponse.clone())) ??
|
|
149
|
+
codeGrantResponse;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
let profile: Profile = {};
|
|
153
|
+
|
|
154
|
+
// ConvexAuth: We use the value of the nonce later, aside from feeding it into the
|
|
155
|
+
// `processAuthorizationCodeResponse` function.
|
|
156
|
+
const nonce = await checks.nonce.use(cookies, resCookies, options);
|
|
157
|
+
|
|
158
|
+
const isOidc = isOIDCProvider(provider);
|
|
159
|
+
const processedCodeResponse = await o.processAuthorizationCodeResponse(
|
|
160
|
+
as,
|
|
161
|
+
client,
|
|
162
|
+
codeGrantResponse,
|
|
163
|
+
{
|
|
164
|
+
expectedNonce: nonce,
|
|
165
|
+
requireIdToken: isOidc,
|
|
166
|
+
},
|
|
167
|
+
);
|
|
168
|
+
|
|
169
|
+
const tokens: TokenSet & Pick<Account, "expires_at"> = processedCodeResponse;
|
|
170
|
+
|
|
171
|
+
if (isOidc) {
|
|
172
|
+
// ConvexAuth: the next few lines are changed slightly to make TypeScript happy
|
|
173
|
+
const idTokenClaimsOrUndefined = o.getValidatedIdTokenClaims(
|
|
174
|
+
processedCodeResponse,
|
|
175
|
+
);
|
|
176
|
+
if (idTokenClaimsOrUndefined === undefined) {
|
|
177
|
+
throw new Error("ID Token claims are missing");
|
|
178
|
+
}
|
|
179
|
+
const idTokenClaims = idTokenClaimsOrUndefined;
|
|
180
|
+
profile = idTokenClaims;
|
|
181
|
+
|
|
182
|
+
// Apple sends some of the user information in a `user` parameter as a stringified JSON.
|
|
183
|
+
// It also only does so the first time the user consents to share their information.
|
|
184
|
+
if (provider.id === "apple") {
|
|
185
|
+
try {
|
|
186
|
+
profile.user = JSON.parse(params?.user)
|
|
187
|
+
// ConvexAuth: disabled lint for empty block
|
|
188
|
+
// eslint-disable-next-line no-empty
|
|
189
|
+
} catch {}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (provider.idToken === false) {
|
|
193
|
+
const userinfoResponse = await o.userInfoRequest(
|
|
194
|
+
as,
|
|
195
|
+
client,
|
|
196
|
+
processedCodeResponse.access_token,
|
|
197
|
+
{
|
|
198
|
+
...fetchOpt(provider),
|
|
199
|
+
// TODO: move away from allowing insecure HTTP requests
|
|
200
|
+
[o.allowInsecureRequests]: true,
|
|
201
|
+
},
|
|
202
|
+
);
|
|
203
|
+
|
|
204
|
+
profile = await o.processUserInfoResponse(
|
|
205
|
+
as,
|
|
206
|
+
client,
|
|
207
|
+
idTokenClaims.sub,
|
|
208
|
+
userinfoResponse,
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
if (userinfo?.request) {
|
|
213
|
+
const _profile = await userinfo.request({ tokens, provider });
|
|
214
|
+
if (_profile instanceof Object) profile = _profile;
|
|
215
|
+
} else if (userinfo?.url) {
|
|
216
|
+
const userinfoResponse = await o.userInfoRequest(
|
|
217
|
+
as,
|
|
218
|
+
client,
|
|
219
|
+
processedCodeResponse.access_token,
|
|
220
|
+
fetchOpt(provider),
|
|
221
|
+
);
|
|
222
|
+
profile = await userinfoResponse.json();
|
|
223
|
+
} else {
|
|
224
|
+
throw new TypeError("No userinfo endpoint configured");
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
if (tokens.expires_in) {
|
|
229
|
+
tokens.expires_at =
|
|
230
|
+
Math.floor(Date.now() / 1000) + Number(tokens.expires_in);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// ConvexAuth: The Auth.js code would handle user + account creation here, but for
|
|
234
|
+
// ConvexAuth we want to handle that in a Convex function. Instead, we return the
|
|
235
|
+
// information needed for the mutation.
|
|
236
|
+
|
|
237
|
+
return {
|
|
238
|
+
profile,
|
|
239
|
+
tokens,
|
|
240
|
+
cookies: resCookies,
|
|
241
|
+
signature: getAuthorizationSignature({ codeVerifier, state, nonce }),
|
|
242
|
+
};
|
|
243
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// This maps to packages/core/src/lib/actions/callback/oauth/checks.ts in the @auth/core package (commit 5af1f30a32e64591abc50ae4d2dba4682e525431)
|
|
2
|
+
|
|
3
|
+
import * as o from "oauth4webapi";
|
|
4
|
+
|
|
5
|
+
import type { InternalOptions } from "./types.js";
|
|
6
|
+
import { Cookie } from "@auth/core/lib/utils/cookie.js";
|
|
7
|
+
import { CookiesOptions } from "@auth/core/types.js";
|
|
8
|
+
import { logWithLevel } from "../implementation/utils.js";
|
|
9
|
+
|
|
10
|
+
const COOKIE_TTL = 60 * 15; // 15 minutes
|
|
11
|
+
|
|
12
|
+
/** Returns a cookie with the given payload and options. */
|
|
13
|
+
// ConvexAuth: Auth.js calls this `sealCookie` and encrypts the payload wrapped in a JWT.
|
|
14
|
+
async function createCookie(
|
|
15
|
+
name: keyof CookiesOptions,
|
|
16
|
+
payload: string,
|
|
17
|
+
options: InternalOptions<"oauth" | "oidc">,
|
|
18
|
+
): Promise<Cookie> {
|
|
19
|
+
const { cookies } = options;
|
|
20
|
+
const cookie = cookies[name];
|
|
21
|
+
const expires = new Date();
|
|
22
|
+
expires.setTime(expires.getTime() + COOKIE_TTL * 1000);
|
|
23
|
+
|
|
24
|
+
logWithLevel("DEBUG", `CREATE_${name.toUpperCase()}`, {
|
|
25
|
+
name: cookie.name,
|
|
26
|
+
payload,
|
|
27
|
+
COOKIE_TTL,
|
|
28
|
+
expires,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const cookieOptions = { ...cookie.options, expires };
|
|
32
|
+
|
|
33
|
+
return { name: cookie.name, value: payload, options: cookieOptions };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function clearCookie(
|
|
37
|
+
name: keyof CookiesOptions,
|
|
38
|
+
options: InternalOptions<"oauth" | "oidc">,
|
|
39
|
+
resCookies: Cookie[],
|
|
40
|
+
) {
|
|
41
|
+
const { cookies } = options;
|
|
42
|
+
const cookie = cookies[name];
|
|
43
|
+
logWithLevel("DEBUG", `CLEAR_${name.toUpperCase()}`, { cookie });
|
|
44
|
+
resCookies.push({
|
|
45
|
+
name: cookie.name,
|
|
46
|
+
value: "",
|
|
47
|
+
options: { ...cookies[name].options, maxAge: 0 },
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function useCookie(
|
|
52
|
+
check: "state" | "pkce" | "nonce",
|
|
53
|
+
name: keyof CookiesOptions,
|
|
54
|
+
) {
|
|
55
|
+
return async function (
|
|
56
|
+
// ConvexAuth: `cookies` is a Record<string, string | undefined> instead of RequestInternal["cookies"]
|
|
57
|
+
cookies: Record<string, string | undefined>,
|
|
58
|
+
resCookies: Cookie[],
|
|
59
|
+
options: InternalOptions<"oidc">,
|
|
60
|
+
) {
|
|
61
|
+
const { provider } = options;
|
|
62
|
+
if (!provider?.checks?.includes(check)) return;
|
|
63
|
+
const cookieValue = cookies?.[options.cookies[name].name];
|
|
64
|
+
logWithLevel("DEBUG", `USE_${name.toUpperCase()}`, { value: cookieValue });
|
|
65
|
+
clearCookie(name, options, resCookies);
|
|
66
|
+
return cookieValue;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @see https://www.rfc-editor.org/rfc/rfc7636
|
|
72
|
+
* @see https://danielfett.de/2020/05/16/pkce-vs-nonce-equivalent-or-not/#pkce
|
|
73
|
+
*/
|
|
74
|
+
export const pkce = {
|
|
75
|
+
/** Creates a PKCE code challenge and verifier pair. The verifier is stored in the cookie. */
|
|
76
|
+
async create(options: InternalOptions<"oauth">) {
|
|
77
|
+
const codeVerifier = o.generateRandomCodeVerifier();
|
|
78
|
+
const codeChallenge = await o.calculatePKCECodeChallenge(codeVerifier);
|
|
79
|
+
const cookie = await createCookie("pkceCodeVerifier", codeVerifier, options);
|
|
80
|
+
return { cookie, codeChallenge: codeChallenge, codeVerifier };
|
|
81
|
+
},
|
|
82
|
+
/**
|
|
83
|
+
* Returns code_verifier if the provider is configured to use PKCE,
|
|
84
|
+
* and clears the container cookie afterwards.
|
|
85
|
+
* An error is thrown if the code_verifier is missing or invalid.
|
|
86
|
+
*/
|
|
87
|
+
use: useCookie("pkce", "pkceCodeVerifier"),
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @see https://www.rfc-editor.org/rfc/rfc6749#section-10.12
|
|
92
|
+
* @see https://www.rfc-editor.org/rfc/rfc6749#section-4.1.1
|
|
93
|
+
*/
|
|
94
|
+
export const state = {
|
|
95
|
+
/** Creates a state cookie with an optionally encoded body. */
|
|
96
|
+
async create(options: InternalOptions<"oauth">, origin?: string) {
|
|
97
|
+
const { provider } = options;
|
|
98
|
+
if (!provider.checks.includes("state")) {
|
|
99
|
+
if (origin) {
|
|
100
|
+
throw new Error(
|
|
101
|
+
"State data was provided but the provider is not configured to use state",
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const payload = o.generateRandomState();
|
|
108
|
+
const cookie = await createCookie("state", payload, options);
|
|
109
|
+
return { cookie, value: payload };
|
|
110
|
+
},
|
|
111
|
+
/**
|
|
112
|
+
* Returns state if the provider is configured to use state,
|
|
113
|
+
* and clears the container cookie afterwards.
|
|
114
|
+
* An error is thrown if the state is missing or invalid.
|
|
115
|
+
*/
|
|
116
|
+
use: useCookie("state", "state"),
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export const nonce = {
|
|
120
|
+
async create(options: InternalOptions<"oidc">) {
|
|
121
|
+
if (!options.provider.checks.includes("nonce")) return;
|
|
122
|
+
const value = o.generateRandomNonce();
|
|
123
|
+
const cookie = await createCookie("nonce", value, options);
|
|
124
|
+
return { cookie, value };
|
|
125
|
+
},
|
|
126
|
+
/**
|
|
127
|
+
* Returns nonce if the provider is configured to use nonce,
|
|
128
|
+
* and clears the container cookie afterwards.
|
|
129
|
+
* An error is thrown if the nonce is missing or invalid.
|
|
130
|
+
* @see https://openid.net/specs/openid-connect-core-1_0.html#NonceNotes
|
|
131
|
+
* @see https://danielfett.de/2020/05/16/pkce-vs-nonce-equivalent-or-not/#nonce
|
|
132
|
+
*/
|
|
133
|
+
use: useCookie("nonce", "nonce"),
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
// ConvexAuth: All WebAuthn checks are omitted.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { CookieOption, CookiesOptions } from "@auth/core/types.js";
|
|
2
|
+
import { requireEnv } from "../utils.js";
|
|
3
|
+
import { InternalProvider } from "./types.js";
|
|
4
|
+
import { SHARED_COOKIE_OPTIONS } from "../cookies.js";
|
|
5
|
+
import { fetchOpt } from "./lib/utils/customFetch.js";
|
|
6
|
+
import * as o from "oauth4webapi";
|
|
7
|
+
import { normalizeEndpoint } from "../provider_utils.js";
|
|
8
|
+
import { isLocalHost } from "../utils.js";
|
|
9
|
+
import { OAuthConfig } from "@auth/core/providers/oauth.js";
|
|
10
|
+
|
|
11
|
+
// ConvexAuth: The logic for the callback URL is different from Auth.js
|
|
12
|
+
export function callbackUrl(providerId: string) {
|
|
13
|
+
return (process.env.CUSTOM_AUTH_SITE_URL ?? requireEnv("CONVEX_SITE_URL")) + "/api/auth/callback/" + providerId;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// ConvexAuth: This is a ConvexAuth specific function that produces a string that the
|
|
17
|
+
// Convex functions will validate
|
|
18
|
+
export function getAuthorizationSignature({
|
|
19
|
+
codeVerifier,
|
|
20
|
+
state,
|
|
21
|
+
nonce,
|
|
22
|
+
}: {
|
|
23
|
+
codeVerifier?: string;
|
|
24
|
+
state?: string;
|
|
25
|
+
nonce?: string;
|
|
26
|
+
}) {
|
|
27
|
+
return [codeVerifier, state, nonce]
|
|
28
|
+
.filter((param) => param !== undefined)
|
|
29
|
+
.join(" ");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function oauthStateCookieName(
|
|
33
|
+
type: "state" | "pkce" | "nonce",
|
|
34
|
+
providerId: string,
|
|
35
|
+
) {
|
|
36
|
+
return (!isLocalHost(process.env.CONVEX_SITE_URL) ? "__Host-" : "") + providerId + "OAuth" + type;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const defaultCookiesOptions: (
|
|
40
|
+
providerId: string,
|
|
41
|
+
) => Record<keyof CookiesOptions, CookieOption> = (providerId) => {
|
|
42
|
+
return {
|
|
43
|
+
pkceCodeVerifier: {
|
|
44
|
+
name: oauthStateCookieName("pkce", providerId),
|
|
45
|
+
options: {
|
|
46
|
+
...SHARED_COOKIE_OPTIONS,
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
state: {
|
|
50
|
+
name: oauthStateCookieName("state", providerId),
|
|
51
|
+
options: {
|
|
52
|
+
...SHARED_COOKIE_OPTIONS,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
nonce: {
|
|
56
|
+
name: oauthStateCookieName("nonce", providerId),
|
|
57
|
+
options: {
|
|
58
|
+
...SHARED_COOKIE_OPTIONS,
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
// ConvexAuth: We don't support webauthn, so this value doesn't actually matter
|
|
62
|
+
webauthnChallenge: {
|
|
63
|
+
name: "ConvexAuth_shouldNotBeUsed_webauthnChallenge",
|
|
64
|
+
options: {
|
|
65
|
+
...SHARED_COOKIE_OPTIONS,
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
// ConvexAuth: We don't use these cookies, so their values should never be used
|
|
69
|
+
sessionToken: {
|
|
70
|
+
name: "ConvexAuth_shouldNotBeUsed_sessionToken",
|
|
71
|
+
options: {
|
|
72
|
+
...SHARED_COOKIE_OPTIONS,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
callbackUrl: {
|
|
76
|
+
name: "ConvexAuth_shouldNotBeUsed_callbackUrl",
|
|
77
|
+
options: {
|
|
78
|
+
...SHARED_COOKIE_OPTIONS,
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
csrfToken: {
|
|
82
|
+
name: "ConvexAuth_shouldNotBeUsed_csrfToken",
|
|
83
|
+
options: {
|
|
84
|
+
...SHARED_COOKIE_OPTIONS,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
export async function oAuthConfigToInternalProvider(config: OAuthConfig<any>): Promise<InternalProvider<"oauth" | "oidc">> {
|
|
91
|
+
// Only do service discovery if the provider does not have the required configuration
|
|
92
|
+
if (!config.authorization || !config.token || !config.userinfo) {
|
|
93
|
+
// Taken from https://github.com/nextauthjs/next-auth/blob/a7491dcb9355ff2d01fb8e9236636605e2090145/packages/core/src/lib/actions/callback/oauth/callback.ts#L63
|
|
94
|
+
if (!config.issuer) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Provider \`${config.id}\` is missing an \`issuer\` URL configuration. Consult the provider docs.`,
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const issuer = new URL(config.issuer);
|
|
101
|
+
// TODO: move away from allowing insecure HTTP requests
|
|
102
|
+
const discoveryResponse = await o.discoveryRequest(issuer, {
|
|
103
|
+
...fetchOpt(config),
|
|
104
|
+
[o.allowInsecureRequests]: true,
|
|
105
|
+
});
|
|
106
|
+
const discoveredAs = await o.processDiscoveryResponse(
|
|
107
|
+
issuer,
|
|
108
|
+
discoveryResponse,
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
if (!discoveredAs.token_endpoint)
|
|
112
|
+
throw new TypeError(
|
|
113
|
+
"TODO: Authorization server did not provide a token endpoint.",
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const as: o.AuthorizationServer = discoveredAs;
|
|
117
|
+
return {
|
|
118
|
+
...config,
|
|
119
|
+
checks: config.checks!,
|
|
120
|
+
profile: config.profile!,
|
|
121
|
+
account: config.account!,
|
|
122
|
+
clientId: config.clientId!,
|
|
123
|
+
idToken: config.type === "oidc" ? config.idToken : undefined,
|
|
124
|
+
// ConvexAuth: Apparently it's important for us to normalize the endpoint after
|
|
125
|
+
// service discovery (https://github.com/get-convex/convex-auth/commit/35bf716bfb0d29dbce1cbca318973b0732f75015)
|
|
126
|
+
authorization: normalizeEndpoint({
|
|
127
|
+
...config.authorization,
|
|
128
|
+
url: as.authorization_endpoint,
|
|
129
|
+
}),
|
|
130
|
+
token: normalizeEndpoint({
|
|
131
|
+
...config.token,
|
|
132
|
+
url: as.token_endpoint,
|
|
133
|
+
}),
|
|
134
|
+
userinfo: as.userinfo_endpoint
|
|
135
|
+
? normalizeEndpoint({
|
|
136
|
+
...config.userinfo,
|
|
137
|
+
url: as.userinfo_endpoint,
|
|
138
|
+
})
|
|
139
|
+
: config.userinfo,
|
|
140
|
+
as,
|
|
141
|
+
configSource: "discovered"
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const authorization = normalizeEndpoint(config.authorization);
|
|
146
|
+
const token = normalizeEndpoint(config.token);
|
|
147
|
+
const userinfo = config.userinfo
|
|
148
|
+
? normalizeEndpoint(config.userinfo)
|
|
149
|
+
: undefined;
|
|
150
|
+
return {
|
|
151
|
+
...config,
|
|
152
|
+
checks: config.checks!,
|
|
153
|
+
profile: config.profile!,
|
|
154
|
+
account: config.account!,
|
|
155
|
+
clientId: config.clientId!,
|
|
156
|
+
idToken: config.type === "oidc" ? config.idToken : undefined,
|
|
157
|
+
authorization,
|
|
158
|
+
token,
|
|
159
|
+
userinfo,
|
|
160
|
+
as: {
|
|
161
|
+
issuer: config.issuer ?? "theremustbeastringhere.dev",
|
|
162
|
+
authorization_endpoint: authorization?.url.toString(),
|
|
163
|
+
token_endpoint: token?.url.toString(),
|
|
164
|
+
userinfo_endpoint: userinfo?.url.toString(),
|
|
165
|
+
},
|
|
166
|
+
configSource: "provided",
|
|
167
|
+
};
|
|
168
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// This file is adapted from packages/core/src/lib/utils/custom-fetch.ts in the @auth/core package (commit 5af1f30a32e64591abc50ae4d2dba4682e525431).
|
|
2
|
+
|
|
3
|
+
import * as o from "oauth4webapi";
|
|
4
|
+
import type { InternalProvider } from "../../types";
|
|
5
|
+
import { customFetch } from "@auth/core";
|
|
6
|
+
import { OAuthConfig } from "@auth/core/providers/index.js";
|
|
7
|
+
// ConvexAuth:re-export the symbol from @auth/core
|
|
8
|
+
export { customFetch } from "@auth/core";
|
|
9
|
+
|
|
10
|
+
type FetchOptResult = {
|
|
11
|
+
[o.customFetch]: typeof fetch;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
// ConvexAuth: Expose this internal function so we can use it.
|
|
15
|
+
// ConvexAuth: Make a version that works on InternalProvider and OAuthConfig
|
|
16
|
+
export function fetchOpt(providerOrConfig: InternalProvider<"oauth" | "oidc"> | OAuthConfig<any>): FetchOptResult {
|
|
17
|
+
return { [o.customFetch]: providerOrConfig[customFetch] ?? fetch };
|
|
18
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// This file maps to packages/core/src/lib/utils/providers.ts in the @auth/core package (commit 5af1f30a32e64591abc50ae4d2dba4682e525431).
|
|
2
|
+
|
|
3
|
+
import { InternalProvider } from "../../types.js";
|
|
4
|
+
|
|
5
|
+
export function isOIDCProvider(
|
|
6
|
+
provider: InternalProvider<"oidc" | "oauth">,
|
|
7
|
+
): provider is InternalProvider<"oidc"> {
|
|
8
|
+
return provider.type === "oidc";
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// ConvexAuth: There are several more functions in the original file which we don't need,
|
|
12
|
+
// and are omitted here.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// This maps to packages/core/src/providers/oauth.ts in the @auth/core package (commit 5af1f30a32e64591abc50ae4d2dba4682e525431)
|
|
2
|
+
|
|
3
|
+
// ConvexAuth: only a few types were brought in.
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
OAuth2Config,
|
|
7
|
+
OAuthConfig,
|
|
8
|
+
OAuthEndpointType,
|
|
9
|
+
OIDCConfig,
|
|
10
|
+
TokenEndpointHandler,
|
|
11
|
+
UserinfoEndpointHandler,
|
|
12
|
+
} from "@auth/core/providers/index.js";
|
|
13
|
+
import { PrivateKey } from "oauth4webapi";
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* We parsed `authorization`, `token` and `userinfo`
|
|
17
|
+
* to always contain a valid `URL`, with the params
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export type OAuthConfigInternal<Profile> = Omit<
|
|
21
|
+
OAuthConfig<Profile>,
|
|
22
|
+
OAuthEndpointType | "redirectProxyUrl"
|
|
23
|
+
> & {
|
|
24
|
+
authorization?: { url: URL };
|
|
25
|
+
token?: {
|
|
26
|
+
url: URL;
|
|
27
|
+
request?: TokenEndpointHandler["request"];
|
|
28
|
+
clientPrivateKey?: CryptoKey | PrivateKey;
|
|
29
|
+
/**
|
|
30
|
+
* @internal
|
|
31
|
+
* @deprecated
|
|
32
|
+
*/
|
|
33
|
+
conform?: TokenEndpointHandler["conform"];
|
|
34
|
+
};
|
|
35
|
+
userinfo?: { url: URL; request?: UserinfoEndpointHandler["request"] };
|
|
36
|
+
/**
|
|
37
|
+
* Reconstructed from {@link OAuth2Config.redirectProxyUrl},
|
|
38
|
+
* adding the callback action and provider id onto the URL.
|
|
39
|
+
*
|
|
40
|
+
* If defined, it is favoured over {@link OAuthConfigInternal.callbackUrl} in the authorization request.
|
|
41
|
+
*
|
|
42
|
+
* When {@link InternalOptions.isOnRedirectProxy} is set, the actual value is saved in the decoded `state.origin` parameter.
|
|
43
|
+
*
|
|
44
|
+
* @example `"https://auth.example.com/api/auth/callback/:provider"`
|
|
45
|
+
*
|
|
46
|
+
*/
|
|
47
|
+
redirectProxyUrl?: OAuth2Config<Profile>["redirectProxyUrl"];
|
|
48
|
+
} & Pick<
|
|
49
|
+
Required<OAuthConfig<Profile>>,
|
|
50
|
+
"clientId" | "checks" | "profile" | "account"
|
|
51
|
+
>;
|
|
52
|
+
|
|
53
|
+
export type OIDCConfigInternal<Profile> = OAuthConfigInternal<Profile> & {
|
|
54
|
+
checks: OIDCConfig<Profile>["checks"];
|
|
55
|
+
idToken: OIDCConfig<Profile>["idToken"];
|
|
56
|
+
};
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// This maps to packages/core/src/types.ts in the @auth/core package (commit 5af1f30a32e64591abc50ae4d2dba4682e525431).
|
|
2
|
+
|
|
3
|
+
import * as AuthCoreJwt from "@auth/core/jwt";
|
|
4
|
+
import { CookieOption, CookiesOptions } from "@auth/core/types.js";
|
|
5
|
+
import { OAuthConfigInternal, OIDCConfigInternal } from "./providers/oauth.js";
|
|
6
|
+
import { ProviderType } from "@auth/core/providers/index.js";
|
|
7
|
+
import * as o from "oauth4webapi";
|
|
8
|
+
|
|
9
|
+
export type ConvexAuthProviderType = "oauth" | "oidc";
|
|
10
|
+
|
|
11
|
+
export type ConfigSource = "discovered" | "provided";
|
|
12
|
+
|
|
13
|
+
// ConvexAuth: Auth.js has a more complex type for this, ours is stripped down.
|
|
14
|
+
export type InternalProvider<T = ProviderType> = (T extends "oauth"
|
|
15
|
+
? OAuthConfigInternal<any>
|
|
16
|
+
: T extends "oidc"
|
|
17
|
+
? OIDCConfigInternal<any>
|
|
18
|
+
: never) & {as: o.AuthorizationServer, configSource: ConfigSource}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
// ConvexAuth: `secret` is internal to @auth/core, so we copy its type here
|
|
22
|
+
export type JWTOptions = AuthCoreJwt.JWTOptions & { secret: string | string[] };
|
|
23
|
+
|
|
24
|
+
/** @internal */
|
|
25
|
+
export interface InternalOptions<TProviderType extends ConvexAuthProviderType> {
|
|
26
|
+
// providers: InternalProvider<TProviderType>[];
|
|
27
|
+
// url: URL;
|
|
28
|
+
// ConvexAuth: omit this option for now
|
|
29
|
+
// action: AuthAction;
|
|
30
|
+
provider: InternalProvider<TProviderType>;
|
|
31
|
+
// csrfToken?: string;
|
|
32
|
+
/**
|
|
33
|
+
* `true` if the [Double-submit CSRF check](https://owasp.org/www-chapter-london/assets/slides/David_Johansson-Double_Defeat_of_Double-Submit_Cookie.pdf) was succesful
|
|
34
|
+
* or [`skipCSRFCheck`](https://authjs.dev/reference/core#skipcsrfcheck) was enabled.
|
|
35
|
+
*/
|
|
36
|
+
// csrfTokenVerified?: boolean;
|
|
37
|
+
// secret: string | string[];
|
|
38
|
+
// ConvexAuth: omit the following options for now
|
|
39
|
+
// theme: Theme;
|
|
40
|
+
// debug: boolean;
|
|
41
|
+
// logger: LoggerInstance;
|
|
42
|
+
// session: NonNullable<Required<AuthConfig["session"]>>;
|
|
43
|
+
// pages: Partial<PagesOptions>;
|
|
44
|
+
// jwt: JWTOptions;
|
|
45
|
+
// events: NonNullable<AuthConfig["events"]>;
|
|
46
|
+
// adapter: Required<Adapter> | undefined;
|
|
47
|
+
// callbacks: NonNullable<Required<AuthConfig["callbacks"]>>;
|
|
48
|
+
cookies: Record<keyof CookiesOptions, CookieOption>;
|
|
49
|
+
// callbackUrl: string;
|
|
50
|
+
/**
|
|
51
|
+
* If true, the OAuth callback is being proxied by the server to the original URL.
|
|
52
|
+
* See also {@link OAuthConfigInternal.redirectProxyUrl}.
|
|
53
|
+
*/
|
|
54
|
+
// isOnRedirectProxy: boolean;
|
|
55
|
+
// experimental: NonNullable<AuthConfig["experimental"]>;
|
|
56
|
+
// basePath: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ConvexAuth: There are several more types in the original file which we don't need,
|
|
60
|
+
// and are omitted here.
|