diff --git a/_doc/notes.mb b/_doc/notes.mb index a833b61..26e9cbd 100644 --- a/_doc/notes.mb +++ b/_doc/notes.mb @@ -179,4 +179,8 @@ ncu ncu -u -# fix (Got an error reading communication packets) ??? \ No newline at end of file +# fix (Got an error reading communication packets) ??? + + +enable apple ID: +curl https://gist.githubusercontent.com/balazsorban44/09613175e7b37ec03f676dcefb7be5eb/raw/b0d31aa0c7f58e0088fdf59ec30cad1415a3475b/apple-gen-secret.mjs -o apple-gen-secret.mjs diff --git a/apple-gen-secret.mjs b/apple-gen-secret.mjs new file mode 100644 index 0000000..f65fb43 --- /dev/null +++ b/apple-gen-secret.mjs @@ -0,0 +1,66 @@ +#!/bin/node + +import { SignJWT } from "jose" +import { createPrivateKey } from "crypto" + +if (process.argv.includes("--help") || process.argv.includes("-h")) { + console.log(` + Creates a JWT from the components found at Apple. + By default, the JWT has a 6 months expiry date. + Read more: https://developer.apple.com/documentation/sign_in_with_apple/generate_and_validate_tokens#3262048 + + Usage: + node apple.mjs [--kid] [--iss] [--private_key] [--sub] [--expires_in] [--exp] + + Options: + --help Print this help message + --kid, --key_id The key id of the private key + --iss, --team_id The Apple team ID + --private_key The private key to use to sign the JWT. (Starts with -----BEGIN PRIVATE KEY-----) + --sub, --client_id The client id to use in the JWT. + --expires_in Number of seconds from now when the JWT should expire. Defaults to 6 months. + --exp Future date in seconds when the JWT expires + `) +} else { + const args = process.argv.slice(2).reduce((acc, arg, i) => { + if (arg.match(/^--\w/)) { + const key = arg.replace(/^--/, "").toLowerCase() + acc[key] = process.argv[i + 3] + } + return acc + }, {}) + + const { + team_id, + iss = team_id, + + private_key, + + client_id, + sub = client_id, + + key_id, + kid = key_id, + + expires_in = 86400 * 180, + exp = Math.ceil(Date.now() / 1000) + expires_in, + } = args + + /** + * How long is the secret valid in seconds. + * @default 15780000 + */ + const expiresAt = Math.ceil(Date.now() / 1000) + expires_in + const expirationTime = exp ?? expiresAt + console.log(` +Apple client secret generated. Valid until: ${new Date(expirationTime * 1000)} + +${await new SignJWT({}) + .setAudience("https://appleid.apple.com") + .setIssuer(iss) + .setIssuedAt() + .setExpirationTime(expirationTime) + .setSubject(sub) + .setProtectedHeader({ alg: "ES256", kid }) + .sign(createPrivateKey(private_key.replace(/\\n/g, "\n")))}`) +} diff --git a/pages/api/auth/[...nextauth].ts b/pages/api/auth/[...nextauth].ts index d9df1e2..d8bbf82 100644 --- a/pages/api/auth/[...nextauth].ts +++ b/pages/api/auth/[...nextauth].ts @@ -4,7 +4,7 @@ import FacebookProvider from "next-auth/providers/facebook" import GithubProvider from "next-auth/providers/github" import TwitterProvider from "next-auth/providers/twitter" import Auth0Provider from "next-auth/providers/auth0" -// import AppleProvider from "next-auth/providers/apple" +import AppleProvider from "next-auth/providers/apple" import EmailProvider from "next-auth/providers/email" import CredentialsProvider from "next-auth/providers/credentials" import { PrismaAdapter } from "@auth/prisma-adapter" @@ -80,6 +80,10 @@ export const authOptions: NextAuthOptions = { return null; } }), + AppleProvider({ + clientId: process.env.APPLE_ID, + clientSecret: process.env.APPLE_SECRET + }) /* EmailProvider({ server: { @@ -97,23 +101,15 @@ export const authOptions: NextAuthOptions = { // Temporarily removing the Apple provider from the demo site as the // callback URL for it needs updating due to Vercel changing domains /* - Providers.Apple({ - clientId: process.env.APPLE_ID, - clientSecret: { - appleId: process.env.APPLE_ID, - teamId: process.env.APPLE_TEAM_ID, - privateKey: process.env.APPLE_PRIVATE_KEY, - keyId: process.env.APPLE_KEY_ID, - }, - }), + */ //d-popov@abv.bg - Auth0Provider({ - clientId: process.env.AUTH0_ID, - clientSecret: process.env.AUTH0_SECRET, - issuer: process.env.AUTH0_ISSUER, - }), + // Auth0Provider({ + // clientId: process.env.AUTH0_ID, + // clientSecret: process.env.AUTH0_SECRET, + // issuer: process.env.AUTH0_ISSUER, + // }), ], theme: { colorScheme: "light",