@cedarjs/auth-dbauth-setup 7.1.0-rc.34 → 7.1.1-next.468
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/dist/oauth.setupData.d.ts +57 -0
- package/dist/oauth.setupData.d.ts.map +1 -0
- package/dist/oauth.setupData.js +336 -0
- package/dist/setup.d.ts +1 -0
- package/dist/setup.d.ts.map +1 -1
- package/dist/setup.js +5 -0
- package/dist/setupData.d.ts +1 -1
- package/dist/setupData.d.ts.map +1 -1
- package/dist/setupData.js +3 -1
- package/dist/setupHandler.d.ts +1 -1
- package/dist/setupHandler.d.ts.map +1 -1
- package/dist/setupHandler.js +50 -4
- package/dist/shared.js +1 -1
- package/dist/templates/api/functions/auth.oauth.ts.template +364 -0
- package/dist/templates/api/functions/auth.ts.template +37 -0
- package/dist/templates/api/functions/auth.webAuthn.oauth.ts.template +382 -0
- package/dist/templates/api/functions/auth.webAuthn.ts.template +37 -0
- package/dist/webAuthn.setupData.d.ts +1 -1
- package/dist/webAuthn.setupData.d.ts.map +1 -1
- package/dist/webAuthn.setupData.js +4 -3
- package/package.json +6 -6
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { AuthGeneratorCtx } from '@cedarjs/cli-helpers/auth/setupHelpers';
|
|
2
|
+
/**
|
|
3
|
+
* The OAuth providers `cedar setup auth dbAuth --oauth` knows how to
|
|
4
|
+
* configure out of the box. Anything else is served by implementing the
|
|
5
|
+
* `OAuthStrategy` interface, documented at
|
|
6
|
+
* https://cedarjs.com/docs/auth/dbauth#oauth-custom-strategies
|
|
7
|
+
*/
|
|
8
|
+
export declare const KNOWN_OAUTH_PROVIDERS: readonly ["google", "github"];
|
|
9
|
+
export type OAuthProviderName = (typeof KNOWN_OAUTH_PROVIDERS)[number];
|
|
10
|
+
/**
|
|
11
|
+
* Parses the comma-separated value of `--oauth` into a deduped list of
|
|
12
|
+
* provider names, validating every entry against `KNOWN_OAUTH_PROVIDERS`.
|
|
13
|
+
*
|
|
14
|
+
* Returns an empty array when `oauth` is nullish (the flag wasn't passed).
|
|
15
|
+
* Some callers pass `null` explicitly for "flag absent"; others invoke the
|
|
16
|
+
* setup handler programmatically and simply omit the argument, which comes
|
|
17
|
+
* through as `undefined`. Both mean "OAuth disabled".
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseOAuthProviders(oauth: string | null | undefined): OAuthProviderName[];
|
|
20
|
+
export declare const apiPackages: string[];
|
|
21
|
+
export declare const createUserModelTask: {
|
|
22
|
+
title: string;
|
|
23
|
+
task: (ctx: AuthGeneratorCtx) => Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
export declare const webAuthnCreateUserModelTask: {
|
|
26
|
+
title: string;
|
|
27
|
+
task: (ctx: AuthGeneratorCtx) => Promise<void>;
|
|
28
|
+
};
|
|
29
|
+
export declare function envVarNotes(providers: OAuthProviderName[]): string[];
|
|
30
|
+
export declare function notes(): string[];
|
|
31
|
+
export declare function webAuthnOauthNotes(): string[];
|
|
32
|
+
export declare const noteGenerate: string[];
|
|
33
|
+
/**
|
|
34
|
+
* Strips the config for every OAuth provider that wasn't selected out of the
|
|
35
|
+
* `auth.oauth.ts`/`auth.webAuthn.oauth.ts` templates, and drops the marker
|
|
36
|
+
* comments around the config for every provider that was.
|
|
37
|
+
*
|
|
38
|
+
* The templates carry every known provider so there's a single source of
|
|
39
|
+
* truth for the generated file's shape; this function is what turns that
|
|
40
|
+
* into a file that only configures the providers the user actually asked
|
|
41
|
+
* for. It's a pure string transform, so re-running setup (which always
|
|
42
|
+
* starts from a fresh copy of the template) produces byte-identical output.
|
|
43
|
+
*
|
|
44
|
+
* Exported for testing.
|
|
45
|
+
*/
|
|
46
|
+
export declare function pruneOAuthProviders(content: string, providers: OAuthProviderName[]): string;
|
|
47
|
+
/**
|
|
48
|
+
* Rewrites the generated `functions/auth.ts` (or `.js`) in place so it only
|
|
49
|
+
* configures the OAuth providers the user selected with `--oauth`. Runs
|
|
50
|
+
* after `generateAuthApiFiles` has written the fresh, unpruned template, so
|
|
51
|
+
* every run starts from the same source and produces the same result.
|
|
52
|
+
*/
|
|
53
|
+
export declare function configureOAuthProvidersTask(providers: OAuthProviderName[]): {
|
|
54
|
+
title: string;
|
|
55
|
+
task: () => void;
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=oauth.setupData.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth.setupData.d.ts","sourceRoot":"","sources":["../src/oauth.setupData.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AAO9E;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,+BAAgC,CAAA;AAElE,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAA;AAMtE;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC/B,iBAAiB,EAAE,CAqCrB;AAGD,eAAO,MAAM,WAAW,UAAsB,CAAA;AAmB9C,eAAO,MAAM,mBAAmB;;gBAEZ,gBAAgB;CAqBnC,CAAA;AAED,eAAO,MAAM,2BAA2B;;gBAEpB,gBAAgB;CAgCnC,CAAA;AAOD,wBAAgB,WAAW,CAAC,SAAS,EAAE,iBAAiB,EAAE,YAWzD;AAuCD,wBAAgB,KAAK,aAkDpB;AAED,wBAAgB,kBAAkB,aAgEjC;AAED,eAAO,MAAM,YAAY,UAMxB,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,iBAAiB,EAAE,UA2B/B;AAMD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,iBAAiB,EAAE;;;EAsBzE"}
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { colors } from "@cedarjs/cli-helpers/colors";
|
|
4
|
+
import { getPaths } from "@cedarjs/cli-helpers/paths";
|
|
5
|
+
import { isTypeScriptProject } from "@cedarjs/cli-helpers/project";
|
|
6
|
+
import { addModels, functionsPath, hasModel, libPath } from "./shared.js";
|
|
7
|
+
const KNOWN_OAUTH_PROVIDERS = ["google", "github"];
|
|
8
|
+
function isKnownOAuthProvider(value) {
|
|
9
|
+
return KNOWN_OAUTH_PROVIDERS.includes(value);
|
|
10
|
+
}
|
|
11
|
+
function parseOAuthProviders(oauth) {
|
|
12
|
+
if (oauth === null || oauth === void 0) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
const requested = oauth.split(",").map((provider) => provider.trim().toLowerCase()).filter(Boolean);
|
|
16
|
+
const uniqueRequested = [...new Set(requested)];
|
|
17
|
+
if (uniqueRequested.length === 0) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
"--oauth requires at least one provider, e.g. --oauth google,github"
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
const unknownProviders = uniqueRequested.filter(
|
|
23
|
+
(provider) => !isKnownOAuthProvider(provider)
|
|
24
|
+
);
|
|
25
|
+
if (unknownProviders.length > 0) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
`Unknown OAuth provider(s): ${unknownProviders.join(", ")}. Cedar ships built-in support for ${KNOWN_OAUTH_PROVIDERS.join(
|
|
28
|
+
", "
|
|
29
|
+
)}. For any other provider, implement the \`OAuthStrategy\` interface from \`@cedarjs/auth-dbauth-oauth\` -- see https://cedarjs.com/docs/auth/dbauth#oauth-custom-strategies`
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
return uniqueRequested;
|
|
33
|
+
}
|
|
34
|
+
const apiPackages = ["oauth4webapi@^3"];
|
|
35
|
+
const OAUTH_MODEL = `
|
|
36
|
+
model OAuth {
|
|
37
|
+
id String @id @default(uuid())
|
|
38
|
+
provider String
|
|
39
|
+
providerUserId String
|
|
40
|
+
providerUsername String?
|
|
41
|
+
providerEmail String?
|
|
42
|
+
userId String
|
|
43
|
+
user User @relation(fields: [userId], references: [id])
|
|
44
|
+
createdAt DateTime @default(now())
|
|
45
|
+
updatedAt DateTime @updatedAt
|
|
46
|
+
|
|
47
|
+
@@unique([provider, providerUserId])
|
|
48
|
+
@@unique([userId, provider])
|
|
49
|
+
}
|
|
50
|
+
`;
|
|
51
|
+
const createUserModelTask = {
|
|
52
|
+
title: "Creating model `User`...",
|
|
53
|
+
task: async (ctx) => {
|
|
54
|
+
const hasUserModel = await hasModel("User");
|
|
55
|
+
if (hasUserModel && !ctx.force) {
|
|
56
|
+
throw new Error("User model already exists");
|
|
57
|
+
}
|
|
58
|
+
addModels(`
|
|
59
|
+
model User {
|
|
60
|
+
id String @id @default(uuid())
|
|
61
|
+
email String @unique
|
|
62
|
+
hashedPassword String?
|
|
63
|
+
salt String?
|
|
64
|
+
resetToken String?
|
|
65
|
+
resetTokenExpiresAt DateTime?
|
|
66
|
+
oauthIdentities OAuth[]
|
|
67
|
+
createdAt DateTime @default(now())
|
|
68
|
+
updatedAt DateTime @updatedAt
|
|
69
|
+
}
|
|
70
|
+
${OAUTH_MODEL}`);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const webAuthnCreateUserModelTask = {
|
|
74
|
+
title: "Creating model `User`...",
|
|
75
|
+
task: async (ctx) => {
|
|
76
|
+
const hasUserModel = await hasModel("User");
|
|
77
|
+
if (hasUserModel && !ctx.force) {
|
|
78
|
+
throw new Error("User model already exists");
|
|
79
|
+
}
|
|
80
|
+
addModels(`
|
|
81
|
+
model User {
|
|
82
|
+
id String @id @default(uuid())
|
|
83
|
+
email String @unique
|
|
84
|
+
hashedPassword String?
|
|
85
|
+
salt String?
|
|
86
|
+
resetToken String?
|
|
87
|
+
resetTokenExpiresAt DateTime?
|
|
88
|
+
webAuthnChallenge String? @unique
|
|
89
|
+
credentials UserCredential[]
|
|
90
|
+
oauthIdentities OAuth[]
|
|
91
|
+
createdAt DateTime @default(now())
|
|
92
|
+
updatedAt DateTime @updatedAt
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
model UserCredential {
|
|
96
|
+
id String @id
|
|
97
|
+
userId String
|
|
98
|
+
user User @relation(fields: [userId], references: [id])
|
|
99
|
+
publicKey Bytes
|
|
100
|
+
transports String?
|
|
101
|
+
counter BigInt
|
|
102
|
+
}
|
|
103
|
+
${OAUTH_MODEL}`);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
const OAUTH_ENV_VAR_NAMES = {
|
|
107
|
+
google: ["GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET"],
|
|
108
|
+
github: ["GITHUB_CLIENT_ID", "GITHUB_CLIENT_SECRET"]
|
|
109
|
+
};
|
|
110
|
+
function envVarNotes(providers) {
|
|
111
|
+
return [
|
|
112
|
+
"",
|
|
113
|
+
"Add the client id and secret for each configured OAuth provider to your .env file (get these from each provider\u2019s developer console):",
|
|
114
|
+
"",
|
|
115
|
+
...providers.flatMap((provider) => [
|
|
116
|
+
` # ${provider}`,
|
|
117
|
+
...OAUTH_ENV_VAR_NAMES[provider].map((name) => ` ${name}=`)
|
|
118
|
+
])
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
function schemaNotes() {
|
|
122
|
+
return [
|
|
123
|
+
"",
|
|
124
|
+
"You will also need to add an `OAuth` model to your Prisma schema to",
|
|
125
|
+
"keep track of linked provider accounts:",
|
|
126
|
+
"",
|
|
127
|
+
" model OAuth {",
|
|
128
|
+
" id String @id @default(uuid())",
|
|
129
|
+
" provider String",
|
|
130
|
+
" providerUserId String",
|
|
131
|
+
" providerUsername String?",
|
|
132
|
+
" providerEmail String?",
|
|
133
|
+
" userId String",
|
|
134
|
+
" user User @relation(fields: [userId], references: [id])",
|
|
135
|
+
" createdAt DateTime @default(now())",
|
|
136
|
+
" updatedAt DateTime @updatedAt",
|
|
137
|
+
"",
|
|
138
|
+
" @@unique([provider, providerUserId])",
|
|
139
|
+
" @@unique([userId, provider])",
|
|
140
|
+
" }",
|
|
141
|
+
"",
|
|
142
|
+
"Since users can now sign up with just an OAuth provider (no password),",
|
|
143
|
+
"`hashedPassword` and `salt` on your `User` model must be optional (or",
|
|
144
|
+
"have a default value):",
|
|
145
|
+
"",
|
|
146
|
+
" hashedPassword String?",
|
|
147
|
+
" salt String?",
|
|
148
|
+
"",
|
|
149
|
+
"Don't forget to add the inverse relation to `User`:",
|
|
150
|
+
"",
|
|
151
|
+
" oauthIdentities OAuth[]"
|
|
152
|
+
];
|
|
153
|
+
}
|
|
154
|
+
function notes() {
|
|
155
|
+
return [
|
|
156
|
+
`${colors.warning("Done! But you have a little more work to do:")}
|
|
157
|
+
`,
|
|
158
|
+
"You will need to add a couple of fields to your User table in order",
|
|
159
|
+
"to store a hashed password and salt:",
|
|
160
|
+
"",
|
|
161
|
+
" model User {",
|
|
162
|
+
" id String @id @default(uuid())",
|
|
163
|
+
" email String @unique",
|
|
164
|
+
" hashedPassword String? // <\u2500\u2510",
|
|
165
|
+
" salt String? // <\u2500\u2534\u2500 add these lines",
|
|
166
|
+
" resetToken String? // <\u2500\u2524",
|
|
167
|
+
" resetTokenExpiresAt DateTime? // <\u2500\u2518",
|
|
168
|
+
" }",
|
|
169
|
+
...schemaNotes(),
|
|
170
|
+
"",
|
|
171
|
+
"If you expose any of your user data via GraphQL be sure to exclude",
|
|
172
|
+
"`hashedPassword` and `salt` (or whatever you named them) from the",
|
|
173
|
+
"SDL file that defines the fields for your user.",
|
|
174
|
+
"",
|
|
175
|
+
"You'll need to let Cedar know what fields you're using for your users'",
|
|
176
|
+
"`id` and `username` fields. In this case we're using `id` and `email`,",
|
|
177
|
+
"so update those in the `authFields` config in",
|
|
178
|
+
`\`${functionsPath}/auth.js\`. This is also the place to tell Cedar if`,
|
|
179
|
+
"you used a different name for the `hashedPassword`, `salt`,",
|
|
180
|
+
"`resetToken` or `resetTokenExpiresAt`, fields:`",
|
|
181
|
+
"",
|
|
182
|
+
" authFields: {",
|
|
183
|
+
" id: 'id',",
|
|
184
|
+
" username: 'email',",
|
|
185
|
+
" hashedPassword: 'hashedPassword',",
|
|
186
|
+
" salt: 'salt',",
|
|
187
|
+
" resetToken: 'resetToken',",
|
|
188
|
+
" resetTokenExpiresAt: 'resetTokenExpiresAt',",
|
|
189
|
+
" },",
|
|
190
|
+
"",
|
|
191
|
+
"To get the actual user that's logged in, take a look at `getCurrentUser()`",
|
|
192
|
+
`in \`${libPath}/auth.js\`. We default it to something simple, but you may`,
|
|
193
|
+
"use different names for your model or unique ID fields, in which case you",
|
|
194
|
+
"need to update those calls (instructions are in the comment above the code).",
|
|
195
|
+
"",
|
|
196
|
+
"Finally, we created a SESSION_SECRET environment variable for you in",
|
|
197
|
+
`${path.join(getPaths().base, ".env")}. This value should NOT be checked`,
|
|
198
|
+
"into version control and should be unique for each environment you",
|
|
199
|
+
"deploy to. If you ever need to log everyone out of your app at once",
|
|
200
|
+
"change this secret to a new value and deploy. To create a new secret, run:",
|
|
201
|
+
"",
|
|
202
|
+
" yarn cedar generate secret",
|
|
203
|
+
""
|
|
204
|
+
];
|
|
205
|
+
}
|
|
206
|
+
function webAuthnOauthNotes() {
|
|
207
|
+
return [
|
|
208
|
+
`${colors.warning("Done! But you have a little more work to do:")}
|
|
209
|
+
`,
|
|
210
|
+
"You will need to add a couple of fields to your User table in order",
|
|
211
|
+
"to store a hashed password, salt, reset token, and to connect it to",
|
|
212
|
+
"a new UserCredential model to keep track of any devices used with",
|
|
213
|
+
"WebAuthn authentication:",
|
|
214
|
+
"",
|
|
215
|
+
" model User {",
|
|
216
|
+
" id String @id @default(uuid())",
|
|
217
|
+
" email String @unique",
|
|
218
|
+
" hashedPassword String?",
|
|
219
|
+
" salt String?",
|
|
220
|
+
" resetToken String?",
|
|
221
|
+
" resetTokenExpiresAt DateTime?",
|
|
222
|
+
" webAuthnChallenge String? @unique",
|
|
223
|
+
" credentials UserCredential[]",
|
|
224
|
+
" }",
|
|
225
|
+
"",
|
|
226
|
+
" model UserCredential {",
|
|
227
|
+
" id String @id",
|
|
228
|
+
" userId String",
|
|
229
|
+
" user User @relation(fields: [userId], references: [id])",
|
|
230
|
+
" publicKey Bytes",
|
|
231
|
+
" transports String?",
|
|
232
|
+
" counter BigInt",
|
|
233
|
+
" }",
|
|
234
|
+
...schemaNotes(),
|
|
235
|
+
"",
|
|
236
|
+
"If you expose any of your user data via GraphQL be sure to exclude",
|
|
237
|
+
"`hashedPassword` and `salt` (or whatever you named them) from the",
|
|
238
|
+
"SDL file that defines the fields for your user.",
|
|
239
|
+
"",
|
|
240
|
+
"You'll need to let Cedar know what fields you're using for your users'",
|
|
241
|
+
"`id` and `username` fields. In this case we're using `id` and `email`,",
|
|
242
|
+
"so update those in the `authFields` config in",
|
|
243
|
+
`\`${functionsPath}/auth.js\`. This is also the place to tell Cedar if`,
|
|
244
|
+
"you used a different name for the `hashedPassword`, `salt`,",
|
|
245
|
+
"`resetToken` or `resetTokenExpiresAt`, fields:`",
|
|
246
|
+
"",
|
|
247
|
+
" authFields: {",
|
|
248
|
+
" id: 'id',",
|
|
249
|
+
" username: 'email',",
|
|
250
|
+
" hashedPassword: 'hashedPassword',",
|
|
251
|
+
" salt: 'salt',",
|
|
252
|
+
" resetToken: 'resetToken',",
|
|
253
|
+
" resetTokenExpiresAt: 'resetTokenExpiresAt',",
|
|
254
|
+
" challenge: 'webAuthnChallenge'",
|
|
255
|
+
" },",
|
|
256
|
+
"",
|
|
257
|
+
"To get the actual user that's logged in, take a look at `getCurrentUser()`",
|
|
258
|
+
`in \`${libPath}/auth.js\`. We default it to something simple, but you may`,
|
|
259
|
+
"use different names for your model or unique ID fields, in which case you",
|
|
260
|
+
"need to update those calls (instructions are in the comment above the code).",
|
|
261
|
+
"",
|
|
262
|
+
"Finally, we created a SESSION_SECRET environment variable for you in",
|
|
263
|
+
`${path.join(getPaths().base, ".env")}. This value should NOT be checked`,
|
|
264
|
+
"into version control and should be unique for each environment you",
|
|
265
|
+
"deploy to. If you ever need to log everyone out of your app at once",
|
|
266
|
+
"change this secret to a new value and deploy. To create a new secret, run:",
|
|
267
|
+
"",
|
|
268
|
+
" yarn cedar generate secret",
|
|
269
|
+
""
|
|
270
|
+
];
|
|
271
|
+
}
|
|
272
|
+
const noteGenerate = [
|
|
273
|
+
"",
|
|
274
|
+
"Need simple Login, Signup and Forgot Password pages? We've got a generator",
|
|
275
|
+
"for those as well:",
|
|
276
|
+
"",
|
|
277
|
+
" yarn cedar generate dbAuth"
|
|
278
|
+
];
|
|
279
|
+
function pruneOAuthProviders(content, providers) {
|
|
280
|
+
let result = content;
|
|
281
|
+
for (const provider of KNOWN_OAUTH_PROVIDERS) {
|
|
282
|
+
const startMarker = `// @oauth-provider:${provider}`;
|
|
283
|
+
const endMarker = `// @oauth-provider:${provider}:end`;
|
|
284
|
+
const blockPattern = new RegExp(
|
|
285
|
+
`[ \\t]*${escapeRegExp(startMarker)}\\n([\\s\\S]*?)[ \\t]*${escapeRegExp(
|
|
286
|
+
endMarker
|
|
287
|
+
)}\\n`
|
|
288
|
+
);
|
|
289
|
+
if (providers.includes(provider)) {
|
|
290
|
+
result = result.replace(blockPattern, "$1");
|
|
291
|
+
} else {
|
|
292
|
+
result = result.replace(blockPattern, "");
|
|
293
|
+
result = result.replace(
|
|
294
|
+
new RegExp(`^[ \\t]*${provider}Provider,\\n`, "m"),
|
|
295
|
+
""
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return result;
|
|
300
|
+
}
|
|
301
|
+
function escapeRegExp(str) {
|
|
302
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
303
|
+
}
|
|
304
|
+
function configureOAuthProvidersTask(providers) {
|
|
305
|
+
return {
|
|
306
|
+
title: "Configuring selected OAuth providers...",
|
|
307
|
+
task: () => {
|
|
308
|
+
const ext = isTypeScriptProject() ? "ts" : "js";
|
|
309
|
+
const authFunctionPath = path.join(
|
|
310
|
+
getPaths().api.functions,
|
|
311
|
+
`auth.${ext}`
|
|
312
|
+
);
|
|
313
|
+
if (!fs.existsSync(authFunctionPath)) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const content = fs.readFileSync(authFunctionPath, "utf-8");
|
|
317
|
+
const prunedContent = pruneOAuthProviders(content, providers);
|
|
318
|
+
if (prunedContent !== content) {
|
|
319
|
+
fs.writeFileSync(authFunctionPath, prunedContent);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
export {
|
|
325
|
+
KNOWN_OAUTH_PROVIDERS,
|
|
326
|
+
apiPackages,
|
|
327
|
+
configureOAuthProvidersTask,
|
|
328
|
+
createUserModelTask,
|
|
329
|
+
envVarNotes,
|
|
330
|
+
noteGenerate,
|
|
331
|
+
notes,
|
|
332
|
+
parseOAuthProviders,
|
|
333
|
+
pruneOAuthProviders,
|
|
334
|
+
webAuthnCreateUserModelTask,
|
|
335
|
+
webAuthnOauthNotes
|
|
336
|
+
};
|
package/dist/setup.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ export declare const description = "Set up auth for for dbAuth";
|
|
|
4
4
|
export declare function builder(yargs: Argv): void;
|
|
5
5
|
export interface Args {
|
|
6
6
|
webauthn: boolean | null;
|
|
7
|
+
oauth?: string | null;
|
|
7
8
|
createUserModel: boolean | null;
|
|
8
9
|
generateAuthPages: boolean | null;
|
|
9
10
|
force: boolean;
|
package/dist/setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAEjC,eAAO,MAAM,OAAO,WAAW,CAAA;AAC/B,eAAO,MAAM,WAAW,+BAA+B,CAAA;AAEvD,wBAAgB,OAAO,CAAC,KAAK,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAEjC,eAAO,MAAM,OAAO,WAAW,CAAA;AAC/B,eAAO,MAAM,WAAW,+BAA+B,CAAA;AAEvD,wBAAgB,OAAO,CAAC,KAAK,EAAE,IAAI,QAwClC;AAED,MAAM,WAAW,IAAI;IACnB,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAA;IAKxB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,eAAe,EAAE,OAAO,GAAG,IAAI,CAAA;IAC/B,iBAAiB,EAAE,OAAO,GAAG,IAAI,CAAA;IACjC,KAAK,EAAE,OAAO,CAAA;CACf;AAED,eAAO,MAAM,OAAO,GAAU,SAAS,IAAI,kBAG1C,CAAA"}
|
package/dist/setup.js
CHANGED
|
@@ -12,6 +12,11 @@ function builder(yargs) {
|
|
|
12
12
|
default: null,
|
|
13
13
|
description: "Include WebAuthn support (TouchID/FaceID)",
|
|
14
14
|
type: "boolean"
|
|
15
|
+
}).option("oauth", {
|
|
16
|
+
alias: "o",
|
|
17
|
+
default: null,
|
|
18
|
+
description: "Include OAuth support for the given comma-separated providers (google, github), e.g. --oauth google,github",
|
|
19
|
+
type: "string"
|
|
15
20
|
}).option("createUserModel", {
|
|
16
21
|
alias: "u",
|
|
17
22
|
default: null,
|
package/dist/setupData.d.ts
CHANGED
package/dist/setupData.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupData.d.ts","sourceRoot":"","sources":["../src/setupData.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setupData.d.ts","sourceRoot":"","sources":["../src/setupData.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wCAAwC,CAAA;AAS9E,eAAO,MAAM,SAAS;;;CAKrB,CAAA;AAED,eAAO,MAAM,mBAAmB;;gBAEZ,gBAAgB;CAoBnC,CAAA;AAGD,eAAO,MAAM,KAAK,UAsDjB,CAAA;AAED,eAAO,MAAM,qBAAqB,UAwBjC,CAAA;AAED,eAAO,MAAM,YAAY,UAMxB,CAAA;AAED,eAAO,MAAM,cAAc,UAO1B,CAAA"}
|
package/dist/setupData.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { colors } from "@cedarjs/cli-helpers/colors";
|
|
4
|
+
import { getPaths } from "@cedarjs/cli-helpers/paths";
|
|
5
|
+
import { addEnvVarTask } from "@cedarjs/cli-helpers/project";
|
|
4
6
|
import { addModels, functionsPath, hasModel, libPath } from "./shared.js";
|
|
5
7
|
const secret = crypto.randomBytes(32).toString("base64");
|
|
6
8
|
const extraTask = addEnvVarTask(
|
package/dist/setupHandler.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Args } from './setup.js';
|
|
2
|
-
export declare function handler({ webauthn, createUserModel, generateAuthPages, force: forceArg, }: Args): Promise<void>;
|
|
2
|
+
export declare function handler({ webauthn, oauth, createUserModel, generateAuthPages, force: forceArg, }: Args): Promise<void>;
|
|
3
3
|
export declare const createAuthDecoderFunction: {
|
|
4
4
|
title: string;
|
|
5
5
|
task: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupHandler.d.ts","sourceRoot":"","sources":["../src/setupHandler.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setupHandler.d.ts","sourceRoot":"","sources":["../src/setupHandler.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAwBtC,wBAAsB,OAAO,CAAC,EAC5B,QAAQ,EACR,KAAK,EACL,eAAe,EACf,iBAAiB,EACjB,KAAK,EAAE,QAAQ,GAChB,EAAE,IAAI,iBA0GN;AA4ED,eAAO,MAAM,yBAAyB;;;CAuCrC,CAAA"}
|
package/dist/setupHandler.js
CHANGED
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import prompts from "prompts";
|
|
4
|
-
import {
|
|
4
|
+
import { standardAuthHandler } from "@cedarjs/cli-helpers/auth/setupHelpers";
|
|
5
|
+
import { getGraphqlPath } from "@cedarjs/cli-helpers/project";
|
|
6
|
+
import { requireTTYOrExit } from "@cedarjs/cli-helpers/tty";
|
|
7
|
+
import {
|
|
8
|
+
apiPackages as oauthApiPackages,
|
|
9
|
+
configureOAuthProvidersTask,
|
|
10
|
+
createUserModelTask as oauthCreateUserModelTask,
|
|
11
|
+
envVarNotes as oauthEnvVarNotes,
|
|
12
|
+
noteGenerate as oauthNoteGenerate,
|
|
13
|
+
notes as oauthNotes,
|
|
14
|
+
parseOAuthProviders,
|
|
15
|
+
webAuthnCreateUserModelTask as webAuthnOauthCreateUserModelTask,
|
|
16
|
+
webAuthnOauthNotes
|
|
17
|
+
} from "./oauth.setupData.js";
|
|
5
18
|
import {
|
|
6
19
|
notes,
|
|
7
20
|
noteGenerate,
|
|
@@ -26,6 +39,7 @@ import {
|
|
|
26
39
|
} from "./webAuthn.setupData.js";
|
|
27
40
|
async function handler({
|
|
28
41
|
webauthn,
|
|
42
|
+
oauth,
|
|
29
43
|
createUserModel,
|
|
30
44
|
generateAuthPages,
|
|
31
45
|
force: forceArg
|
|
@@ -37,10 +51,22 @@ async function handler({
|
|
|
37
51
|
)
|
|
38
52
|
);
|
|
39
53
|
const webAuthn = await shouldIncludeWebAuthn(webauthn);
|
|
54
|
+
const oauthProviders = parseOAuthProviders(oauth);
|
|
55
|
+
const includeOAuth = oauthProviders.length > 0;
|
|
40
56
|
const createDbUserModel = await shouldCreateUserModel(createUserModel);
|
|
41
57
|
const generateDbAuthPages = await shouldGenerateDbAuthPages(generateAuthPages);
|
|
42
58
|
const oneMoreThing = [];
|
|
43
|
-
if (webAuthn) {
|
|
59
|
+
if (webAuthn && includeOAuth) {
|
|
60
|
+
if (createDbUserModel) {
|
|
61
|
+
oneMoreThing.push(...notesCreatedUserModel);
|
|
62
|
+
} else {
|
|
63
|
+
oneMoreThing.push(...webAuthnOauthNotes());
|
|
64
|
+
}
|
|
65
|
+
oneMoreThing.push(...oauthEnvVarNotes(oauthProviders));
|
|
66
|
+
if (!generateDbAuthPages) {
|
|
67
|
+
oneMoreThing.push(...webAuthnNoteGenerate);
|
|
68
|
+
}
|
|
69
|
+
} else if (webAuthn) {
|
|
44
70
|
if (createDbUserModel) {
|
|
45
71
|
oneMoreThing.push(...notesCreatedUserModel);
|
|
46
72
|
} else {
|
|
@@ -49,6 +75,16 @@ async function handler({
|
|
|
49
75
|
if (!generateDbAuthPages) {
|
|
50
76
|
oneMoreThing.push(...webAuthnNoteGenerate);
|
|
51
77
|
}
|
|
78
|
+
} else if (includeOAuth) {
|
|
79
|
+
if (createDbUserModel) {
|
|
80
|
+
oneMoreThing.push(...notesCreatedUserModel);
|
|
81
|
+
} else {
|
|
82
|
+
oneMoreThing.push(...oauthNotes());
|
|
83
|
+
}
|
|
84
|
+
oneMoreThing.push(...oauthEnvVarNotes(oauthProviders));
|
|
85
|
+
if (!generateDbAuthPages) {
|
|
86
|
+
oneMoreThing.push(...oauthNoteGenerate);
|
|
87
|
+
}
|
|
52
88
|
} else {
|
|
53
89
|
if (createDbUserModel) {
|
|
54
90
|
oneMoreThing.push(...notesCreatedUserModel);
|
|
@@ -62,8 +98,12 @@ async function handler({
|
|
|
62
98
|
oneMoreThing.push(...notePrivateSet);
|
|
63
99
|
let createDbUserModelTask = void 0;
|
|
64
100
|
if (createDbUserModel) {
|
|
65
|
-
if (webAuthn) {
|
|
101
|
+
if (webAuthn && includeOAuth) {
|
|
102
|
+
createDbUserModelTask = webAuthnOauthCreateUserModelTask;
|
|
103
|
+
} else if (webAuthn) {
|
|
66
104
|
createDbUserModelTask = webAuthnCreateUserModelTask;
|
|
105
|
+
} else if (includeOAuth) {
|
|
106
|
+
createDbUserModelTask = oauthCreateUserModelTask;
|
|
67
107
|
} else {
|
|
68
108
|
createDbUserModelTask = createUserModelTask;
|
|
69
109
|
}
|
|
@@ -74,18 +114,21 @@ async function handler({
|
|
|
74
114
|
provider: "dbAuth",
|
|
75
115
|
authDecoderImport: "import { createAuthDecoder } from '@cedarjs/auth-dbauth-api'",
|
|
76
116
|
webAuthn,
|
|
117
|
+
oauth: includeOAuth,
|
|
77
118
|
webPackages: [
|
|
78
119
|
`@cedarjs/auth-dbauth-web@${version}`,
|
|
79
120
|
...webAuthn ? webAuthnWebPackages : []
|
|
80
121
|
],
|
|
81
122
|
apiPackages: [
|
|
82
123
|
`@cedarjs/auth-dbauth-api@${version}`,
|
|
83
|
-
...webAuthn ? webAuthnApiPackages : []
|
|
124
|
+
...webAuthn ? webAuthnApiPackages : [],
|
|
125
|
+
...includeOAuth ? [`@cedarjs/auth-dbauth-oauth@${version}`, ...oauthApiPackages] : []
|
|
84
126
|
],
|
|
85
127
|
extraTasks: [
|
|
86
128
|
webAuthn ? webAuthnExtraTask : extraTask,
|
|
87
129
|
createDbUserModelTask,
|
|
88
130
|
createAuthDecoderFunction,
|
|
131
|
+
includeOAuth ? configureOAuthProvidersTask(oauthProviders) : void 0,
|
|
89
132
|
generateDbAuthPages ? generateAuthPagesTask(createDbUserModel) : void 0
|
|
90
133
|
],
|
|
91
134
|
notes: oneMoreThing
|
|
@@ -93,6 +136,7 @@ async function handler({
|
|
|
93
136
|
}
|
|
94
137
|
async function shouldIncludeWebAuthn(webauthn) {
|
|
95
138
|
if (webauthn === null) {
|
|
139
|
+
requireTTYOrExit("--webauthn or --webauthn=false");
|
|
96
140
|
const webAuthnResponse = await prompts({
|
|
97
141
|
type: "confirm",
|
|
98
142
|
name: "answer",
|
|
@@ -111,6 +155,7 @@ async function shouldCreateUserModel(createUserModel) {
|
|
|
111
155
|
return true;
|
|
112
156
|
}
|
|
113
157
|
if (createUserModel === null && !hasUserModel) {
|
|
158
|
+
requireTTYOrExit("--createUserModel or --createUserModel=false");
|
|
114
159
|
const createModelResponse = await prompts({
|
|
115
160
|
type: "confirm",
|
|
116
161
|
name: "answer",
|
|
@@ -123,6 +168,7 @@ async function shouldCreateUserModel(createUserModel) {
|
|
|
123
168
|
}
|
|
124
169
|
async function shouldGenerateDbAuthPages(generateAuthPages) {
|
|
125
170
|
if (generateAuthPages === null && !hasAuthPages()) {
|
|
171
|
+
requireTTYOrExit("--generateAuthPages or --generateAuthPages=false");
|
|
126
172
|
const generateAuthPagesResponse = await prompts({
|
|
127
173
|
type: "confirm",
|
|
128
174
|
name: "answer",
|
package/dist/shared.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import prismaInternals from "@prisma/internals";
|
|
4
|
-
import { getPaths } from "@cedarjs/cli-helpers";
|
|
5
4
|
import { runBin } from "@cedarjs/cli-helpers/packageManager/exec";
|
|
5
|
+
import { getPaths } from "@cedarjs/cli-helpers/paths";
|
|
6
6
|
import {
|
|
7
7
|
processPagesDir,
|
|
8
8
|
getSchemaPath,
|