Skip to content

Commit 036c62c

Browse files
Enhance authentication setup and improve documentation
Adds automatic auth secret generation, improves environment file handling, creates client env files, adds trusted origins configuration, enhances README generation with better structure and instructions, and updates post-installation guidance with clearer steps.
1 parent 811c849 commit 036c62c

File tree

13 files changed

+265
-134
lines changed

13 files changed

+265
-134
lines changed

.changeset/eight-candies-design.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"create-better-t-stack": patch
3+
---
4+
5+
Enhance authentication setup and improve documentation

apps/cli/src/helpers/addons-setup.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
import path from "node:path";
2-
import { log } from "@clack/prompts";
32
import fs from "fs-extra";
4-
import pc from "picocolors";
53
import type { ProjectAddons } from "../types";
64

75
export async function setupAddons(projectDir: string, addons: ProjectAddons[]) {

apps/cli/src/helpers/auth-setup.ts

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,58 @@ export async function configureAuth(
5050
);
5151
} else {
5252
const envPath = path.join(serverDir, ".env");
53-
const envExamplePath = path.join(serverDir, "_env");
53+
const templateEnvPath = path.join(
54+
PKG_ROOT,
55+
options.orm === "drizzle"
56+
? "template/with-drizzle/packages/server/_env"
57+
: "template/base/packages/server/_env",
58+
);
59+
60+
if (!(await fs.pathExists(envPath))) {
61+
if (await fs.pathExists(templateEnvPath)) {
62+
await fs.copy(templateEnvPath, envPath);
63+
} else {
64+
const defaultEnv = `BETTER_AUTH_SECRET=${generateAuthSecret()}
65+
BETTER_AUTH_URL=http://localhost:3000
66+
CORS_ORIGIN=http://localhost:3001
67+
${options.database === "sqlite" ? "TURSO_CONNECTION_URL=http://127.0.0.1:8080" : ""}
68+
${options.orm === "prisma" ? 'DATABASE_URL="file:./dev.db"' : ""}
69+
`;
70+
await fs.writeFile(envPath, defaultEnv);
71+
}
72+
} else {
73+
let envContent = await fs.readFile(envPath, "utf8");
74+
75+
if (!envContent.includes("BETTER_AUTH_SECRET")) {
76+
envContent += `\nBETTER_AUTH_SECRET=${generateAuthSecret()}`;
77+
}
78+
79+
if (!envContent.includes("BETTER_AUTH_URL")) {
80+
envContent += "\nBETTER_AUTH_URL=http://localhost:3000";
81+
}
82+
83+
if (!envContent.includes("CORS_ORIGIN")) {
84+
envContent += "\nCORS_ORIGIN=http://localhost:3001";
85+
}
86+
87+
if (
88+
options.database === "sqlite" &&
89+
!envContent.includes("TURSO_CONNECTION_URL")
90+
) {
91+
envContent += "\nTURSO_CONNECTION_URL=http://127.0.0.1:8080";
92+
}
93+
94+
if (options.orm === "prisma" && !envContent.includes("DATABASE_URL")) {
95+
envContent += '\nDATABASE_URL="file:./dev.db"';
96+
}
97+
98+
await fs.writeFile(envPath, envContent);
99+
}
54100

55-
if (await fs.pathExists(envExamplePath)) {
56-
await fs.copy(envExamplePath, envPath);
57-
await fs.remove(envExamplePath);
101+
const clientEnvPath = path.join(clientDir, ".env");
102+
if (!(await fs.pathExists(clientEnvPath))) {
103+
const clientEnvContent = "VITE_SERVER_URL=http://localhost:3000\n";
104+
await fs.writeFile(clientEnvPath, clientEnvContent);
58105
}
59106

60107
if (options.orm === "prisma") {
@@ -71,6 +118,15 @@ export async function configureAuth(
71118
await fs.ensureDir(path.dirname(prismaAuthPath));
72119
await fs.copy(defaultPrismaAuthPath, prismaAuthPath);
73120
}
121+
122+
let authContent = await fs.readFile(prismaAuthPath, "utf8");
123+
if (!authContent.includes("trustedOrigins")) {
124+
authContent = authContent.replace(
125+
"export const auth = betterAuth({",
126+
"export const auth = betterAuth({\n trustedOrigins: [process.env.CORS_ORIGIN!],",
127+
);
128+
await fs.writeFile(prismaAuthPath, authContent);
129+
}
74130
} else if (options.orm === "drizzle") {
75131
const drizzleAuthPath = path.join(serverDir, "src/lib/auth.ts");
76132
const defaultDrizzleAuthPath = path.join(
@@ -95,3 +151,14 @@ export async function configureAuth(
95151
throw error;
96152
}
97153
}
154+
155+
function generateAuthSecret(length = 32): string {
156+
const characters =
157+
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
158+
let result = "";
159+
const charactersLength = characters.length;
160+
for (let i = 0; i < length; i++) {
161+
result += characters.charAt(Math.floor(Math.random() * charactersLength));
162+
}
163+
return result;
164+
}

apps/cli/src/helpers/create-project.ts

Lines changed: 25 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -37,27 +37,6 @@ export async function createProject(options: ProjectConfig): Promise<string> {
3737
}
3838
}
3939

40-
const gitignoreFiles = [
41-
[
42-
path.join(projectDir, "_gitignore"),
43-
path.join(projectDir, ".gitignore"),
44-
],
45-
[
46-
path.join(projectDir, "packages/client/_gitignore"),
47-
path.join(projectDir, "packages/client/.gitignore"),
48-
],
49-
[
50-
path.join(projectDir, "packages/server/_gitignore"),
51-
path.join(projectDir, "packages/server/.gitignore"),
52-
],
53-
];
54-
55-
for (const [source, target] of gitignoreFiles) {
56-
if (await fs.pathExists(source)) {
57-
await fs.move(source, target);
58-
}
59-
}
60-
6140
const envFiles = [
6241
[
6342
path.join(projectDir, "packages/server/_env"),
@@ -112,26 +91,31 @@ export async function createProject(options: ProjectConfig): Promise<string> {
11291
: "bun@1.2.4";
11392
}
11493

115-
if (options.auth && options.database !== "none") {
116-
packageJson.scripts["auth:generate"] =
117-
"cd packages/server && npx @better-auth/cli generate --output ./src/db/auth-schema.ts";
118-
119-
if (options.orm === "prisma") {
120-
packageJson.scripts["prisma:generate"] =
121-
"cd packages/server && npx prisma generate";
122-
packageJson.scripts["prisma:push"] =
123-
"cd packages/server && npx prisma db push";
124-
packageJson.scripts["prisma:studio"] =
125-
"cd packages/server && npx prisma studio";
126-
127-
packageJson.scripts["db:setup"] =
128-
"npm run auth:generate && npm run prisma:generate && npm run prisma:push";
129-
} else if (options.orm === "drizzle") {
130-
packageJson.scripts["drizzle:migrate"] =
131-
"cd packages/server && npx @better-auth/cli migrate";
132-
133-
packageJson.scripts["db:setup"] =
134-
"npm run auth:generate && npm run drizzle:migrate";
94+
if (options.database !== "none") {
95+
if (options.database === "sqlite") {
96+
packageJson.scripts["db:local"] =
97+
"cd packages/server && turso dev --db-file local.db";
98+
}
99+
100+
if (options.auth) {
101+
packageJson.scripts["auth:generate"] =
102+
"cd packages/server && npx @better-auth/cli generate --output ./src/db/auth-schema.ts";
103+
104+
if (options.orm === "prisma") {
105+
packageJson.scripts["prisma:generate"] =
106+
"cd packages/server && npx prisma generate";
107+
packageJson.scripts["prisma:push"] =
108+
"cd packages/server && npx prisma db push";
109+
packageJson.scripts["prisma:studio"] =
110+
"cd packages/server && npx prisma studio";
111+
packageJson.scripts["db:setup"] =
112+
"npm run auth:generate && npm run prisma:generate && npm run prisma:push";
113+
} else if (options.orm === "drizzle") {
114+
packageJson.scripts["drizzle:migrate"] =
115+
"cd packages/server && npx @better-auth/cli migrate";
116+
packageJson.scripts["db:setup"] =
117+
"npm run auth:generate && npm run drizzle:migrate";
118+
}
135119
}
136120
}
137121

0 commit comments

Comments
 (0)