Fix GitHub/Google OAuth redirect URI configuration (GRO-546) #257
@@ -171,17 +171,21 @@ export async function initAuth(): Promise<void> {
|
||||
const hasGoogle = !!(process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET);
|
||||
const hasGitHub = !!(process.env.GITHUB_CLIENT_ID && process.env.GITHUB_CLIENT_SECRET);
|
||||
|
||||
const callbackBase = `${BETTER_AUTH_URL}/api/auth/callback`;
|
||||
|
||||
const socialPlugins = [];
|
||||
if (hasGoogle) {
|
||||
socialPlugins.push(google({
|
||||
clientId: process.env.GOOGLE_CLIENT_ID!,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
||||
redirectURI: `${callbackBase}/google`,
|
||||
}));
|
||||
}
|
||||
if (hasGitHub) {
|
||||
socialPlugins.push(github({
|
||||
clientId: process.env.GITHUB_CLIENT_ID!,
|
||||
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
|
||||
redirectURI: `${callbackBase}/github`,
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 184 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Error>
|
||||
<Code>AccessDenied</Code>
|
||||
<Message>You have no right to access this object because of bucket acl.</Message>
|
||||
<RequestId>69D96C853FAECD363909C4A0</RequestId>
|
||||
<HostId>hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com</HostId>
|
||||
<EC>0003-00000001</EC>
|
||||
<RecommendDoc>https://api.alibabacloud.com/troubleshoot?q=0003-00000001</RecommendDoc>
|
||||
</Error>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Error>
|
||||
<Code>AccessDenied</Code>
|
||||
<Message>You have no right to access this object because of bucket acl.</Message>
|
||||
<RequestId>69D96CFC84D7A9333708F278</RequestId>
|
||||
<HostId>hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com</HostId>
|
||||
<EC>0003-00000001</EC>
|
||||
<RecommendDoc>https://api.alibabacloud.com/troubleshoot?q=0003-00000001</RecommendDoc>
|
||||
</Error>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Error>
|
||||
<Code>AccessDenied</Code>
|
||||
<Message>You have no right to access this object because of bucket acl.</Message>
|
||||
<RequestId>69D96D48D7892E37386B9ACB</RequestId>
|
||||
<HostId>hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com</HostId>
|
||||
<EC>0003-00000001</EC>
|
||||
<RecommendDoc>https://api.alibabacloud.com/troubleshoot?q=0003-00000001</RecommendDoc>
|
||||
</Error>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Error>
|
||||
<Code>AccessDenied</Code>
|
||||
<Message>You have no right to access this object because of bucket acl.</Message>
|
||||
<RequestId>69D96C25663D703833F23607</RequestId>
|
||||
<HostId>hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com</HostId>
|
||||
<EC>0003-00000001</EC>
|
||||
<RecommendDoc>https://api.alibabacloud.com/troubleshoot?q=0003-00000001</RecommendDoc>
|
||||
</Error>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Error>
|
||||
<Code>AccessDenied</Code>
|
||||
<Message>You have no right to access this object because of bucket acl.</Message>
|
||||
<RequestId>69D96D89851C843332073968</RequestId>
|
||||
<HostId>hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com</HostId>
|
||||
<EC>0003-00000001</EC>
|
||||
<RecommendDoc>https://api.alibabacloud.com/troubleshoot?q=0003-00000001</RecommendDoc>
|
||||
</Error>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 205 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Error>
|
||||
<Code>AccessDenied</Code>
|
||||
<Message>You have no right to access this object because of bucket acl.</Message>
|
||||
<RequestId>69D96C9C5A03D33730C61AD8</RequestId>
|
||||
<HostId>hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com</HostId>
|
||||
<EC>0003-00000001</EC>
|
||||
<RecommendDoc>https://api.alibabacloud.com/troubleshoot?q=0003-00000001</RecommendDoc>
|
||||
</Error>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 269 KiB |
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Error>
|
||||
<Code>AccessDenied</Code>
|
||||
<Message>You have no right to access this object because of bucket acl.</Message>
|
||||
<RequestId>69D96BEB91911B30317E3BE8</RequestId>
|
||||
<HostId>hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com</HostId>
|
||||
<EC>0003-00000001</EC>
|
||||
<RecommendDoc>https://api.alibabacloud.com/troubleshoot?q=0003-00000001</RecommendDoc>
|
||||
</Error>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Error>
|
||||
<Code>AccessDenied</Code>
|
||||
<Message>You have no right to access this object because of bucket acl.</Message>
|
||||
<RequestId>69D96BFB7B92D33535D6D90D</RequestId>
|
||||
<HostId>hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com</HostId>
|
||||
<EC>0003-00000001</EC>
|
||||
<RecommendDoc>https://api.alibabacloud.com/troubleshoot?q=0003-00000001</RecommendDoc>
|
||||
</Error>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Error>
|
||||
<Code>AccessDenied</Code>
|
||||
<Message>You have no right to access this object because of bucket acl.</Message>
|
||||
<RequestId>69D96B8BDF4B473630A2E120</RequestId>
|
||||
<HostId>hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com</HostId>
|
||||
<EC>0003-00000001</EC>
|
||||
<RecommendDoc>https://api.alibabacloud.com/troubleshoot?q=0003-00000001</RecommendDoc>
|
||||
</Error>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Error>
|
||||
<Code>AccessDenied</Code>
|
||||
<Message>You have no right to access this object because of bucket acl.</Message>
|
||||
<RequestId>69D96D78BFFCAD343037C27C</RequestId>
|
||||
<HostId>hailuo-image-algeng-data-us.oss-us-east-1.aliyuncs.com</HostId>
|
||||
<EC>0003-00000001</EC>
|
||||
<RecommendDoc>https://api.alibabacloud.com/troubleshoot?q=0003-00000001</RecommendDoc>
|
||||
</Error>
|
||||
+1
-1
Submodule infra updated: d43a016f3f...aaedafcb9a
+98
-4
@@ -184,7 +184,7 @@ const dogBreeds = [
|
||||
"Brittany", "English Springer Spaniel", "Maltese", "Bichon Frise",
|
||||
"West Highland White Terrier", "Vizsla", "Chihuahua", "Collie",
|
||||
"Basset Hound", "Newfoundland", "Samoyed", "Australian Shepherd",
|
||||
"Pembroke Welsh Corgi", "French Bulldog", "Weimaraner",
|
||||
"Pembroke Welsh Corgi", "French Bulldog", "Weimaraner", "Puggle",
|
||||
"Mixed Breed", "Mixed Breed", "Mixed Breed",
|
||||
];
|
||||
|
||||
@@ -281,6 +281,44 @@ const productsUsed = [
|
||||
"Coconut oil shampoo, leave-in conditioner, cologne",
|
||||
];
|
||||
|
||||
const demoPetImages = [
|
||||
"/demo-pets/dog-golden-after.png",
|
||||
"/demo-pets/dog-poodle-groomed.png",
|
||||
"/demo-pets/dog-black-lab.png",
|
||||
"/demo-pets/dog-shih-tzu.png",
|
||||
"/demo-pets/dog-cocker-spaniel.png",
|
||||
"/demo-pets/dog-schnauzer.png",
|
||||
"/demo-pets/dog-maltese.png",
|
||||
"/demo-pets/dog-dachshund.png",
|
||||
"/demo-pets/dog-pomeranian.png",
|
||||
"/demo-pets/dog-bichon-frise.png",
|
||||
"/demo-pets/dog-golden-retriever.png",
|
||||
"/demo-pets/dog-labrador.png",
|
||||
"/demo-pets/dog-mixed-breed.png",
|
||||
"/demo-pets/dog-poodle.png",
|
||||
"/demo-pets/dog-terrier.png",
|
||||
"/demo-pets/dog-afghan-hound.png",
|
||||
"/demo-pets/dog-basset-brown-white.png",
|
||||
"/demo-pets/dog-bichon-white-groomed.png",
|
||||
"/demo-pets/dog-boxer-fawn-athletic.png",
|
||||
"/demo-pets/dog-cavalier-cream-gentle.png",
|
||||
"/demo-pets/dog-cocker-buff-friendly.png",
|
||||
"/demo-pets/dog-corgi.png",
|
||||
"/demo-pets/dog-dachshund-black-tan.png",
|
||||
"/demo-pets/dog-golden-before.png",
|
||||
"/demo-pets/dog-pomeranian-white-studio.png",
|
||||
"/demo-pets/dog-schnauzer-black-groomed.png",
|
||||
"/demo-pets/dog-setter-red-sunlit.png",
|
||||
"/demo-pets/dog-sheepdog-merle-running.png",
|
||||
];
|
||||
|
||||
const puggleImages = [
|
||||
"/demo-pets/dog-puggle-fawn-playful.png",
|
||||
"/demo-pets/dog-puggle-black-sitting.png",
|
||||
"/demo-pets/dog-puggle-cream-groomed.png",
|
||||
"/demo-pets/dog-puggle-fawn-grooming.png",
|
||||
];
|
||||
|
||||
// ── Service definitions ──────────────────────────────────────────────────────
|
||||
// Deterministic service IDs + UNIQUE(name) constraint make seed fully idempotent:
|
||||
// first run inserts, subsequent runs update existing rows via ON CONFLICT (name).
|
||||
@@ -368,6 +406,58 @@ async function seedKnownUsers() {
|
||||
}
|
||||
}
|
||||
|
||||
// ── Staff: UAT Super User (oidcSub from SEED_UAT_SUPER_OIDC_SUB env var) ──
|
||||
const uatSuperOidcSub = process.env.SEED_UAT_SUPER_OIDC_SUB;
|
||||
if (uatSuperOidcSub) {
|
||||
const UAT_SUPER_STAFF_ID = "00000000-0000-0000-0000-000000000003";
|
||||
const [existingUatSuper] = await db
|
||||
.select()
|
||||
.from(schema.staff)
|
||||
.where(eq(schema.staff.email, "uat-super@groombook.dev"))
|
||||
.limit(1);
|
||||
|
||||
if (existingUatSuper) {
|
||||
console.log(`✓ Staff 'UAT Super User' already exists — skipping`);
|
||||
} else {
|
||||
await db.insert(schema.staff).values({
|
||||
id: UAT_SUPER_STAFF_ID,
|
||||
name: "UAT Super User",
|
||||
email: "uat-super@groombook.dev",
|
||||
oidcSub: uatSuperOidcSub,
|
||||
role: "manager",
|
||||
isSuperUser: true,
|
||||
active: true,
|
||||
});
|
||||
console.log(`✓ Created staff 'UAT Super User' (oidcSub: ${uatSuperOidcSub})`);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Staff: UAT Staff Groomer (oidcSub from SEED_UAT_STAFF_OIDC_SUB env var) ──
|
||||
const uatStaffOidcSub = process.env.SEED_UAT_STAFF_OIDC_SUB;
|
||||
if (uatStaffOidcSub) {
|
||||
const UAT_STAFF_STAFF_ID = "00000000-0000-0000-0000-000000000004";
|
||||
const [existingUatStaff] = await db
|
||||
.select()
|
||||
.from(schema.staff)
|
||||
.where(eq(schema.staff.email, "uat-groomer@groombook.dev"))
|
||||
.limit(1);
|
||||
|
||||
if (existingUatStaff) {
|
||||
console.log(`✓ Staff 'UAT Staff Groomer' already exists — skipping`);
|
||||
} else {
|
||||
await db.insert(schema.staff).values({
|
||||
id: UAT_STAFF_STAFF_ID,
|
||||
name: "UAT Staff Groomer",
|
||||
email: "uat-groomer@groombook.dev",
|
||||
oidcSub: uatStaffOidcSub,
|
||||
role: "groomer",
|
||||
isSuperUser: false,
|
||||
active: true,
|
||||
});
|
||||
console.log(`✓ Created staff 'UAT Staff Groomer' (oidcSub: ${uatStaffOidcSub})`);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Services: idempotent upsert using name as unique key ─────────────────────
|
||||
// UNIQUE constraint on services.name (migration 0020) must exist first.
|
||||
// Uses b0000001-... IDs to match main seed servicesDef for same-named services.
|
||||
@@ -569,6 +659,7 @@ async function seed() {
|
||||
const clientRecords: ClientRecord[] = [];
|
||||
const petRecords: PetRecord[] = [];
|
||||
|
||||
let petIndex = 0; // Track pet count to assign Puggle images to first 250 pets
|
||||
const clientBatchSize = 50;
|
||||
for (let batch = 0; batch < Math.ceil(cfg.clientCount / clientBatchSize); batch++) {
|
||||
const clientBatch: (typeof schema.clients.$inferInsert)[] = [];
|
||||
@@ -600,7 +691,7 @@ async function seed() {
|
||||
const petCount = rand() < 0.5 ? 1 : rand() < 0.7 ? 2 : 3;
|
||||
for (let p = 0; p < petCount; p++) {
|
||||
const petId = uuid();
|
||||
const breed = pick(dogBreeds);
|
||||
const breed = petIndex < 250 ? "Puggle" : pick(dogBreeds);
|
||||
const dob = new Date(now);
|
||||
dob.setFullYear(dob.getFullYear() - randInt(1, 14));
|
||||
dob.setMonth(randInt(0, 11));
|
||||
@@ -619,9 +710,11 @@ async function seed() {
|
||||
shampooPreference: pick(shampoos),
|
||||
specialCareNotes: rand() < 0.1 ? "Vet clearance required before grooming" : null,
|
||||
customFields: {},
|
||||
image: petIndex < 250 ? pick(puggleImages) : pick(demoPetImages),
|
||||
});
|
||||
|
||||
petRecords.push({ id: petId, clientId });
|
||||
petIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -652,6 +745,7 @@ async function seed() {
|
||||
shampooPreference: pet.shampooPreference,
|
||||
specialCareNotes: pet.specialCareNotes,
|
||||
customFields: pet.customFields,
|
||||
image: pet.image,
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -686,8 +780,8 @@ async function seed() {
|
||||
.values({ id: uc.id, name: uc.name, email: uc.email, phone: uc.phone, address: uc.address })
|
||||
.onConflictDoUpdate({ target: schema.clients.id, set: { name: uc.name, email: uc.email, phone: uc.phone, address: uc.address } });
|
||||
await db.insert(schema.pets)
|
||||
.values({ id: uc.petId, clientId: uc.id, name: uc.petName, species: "Dog", breed: uc.petBreed, weightKg: "25.00", dateOfBirth: new Date("2021-03-15T00:00:00Z") })
|
||||
.onConflictDoUpdate({ target: schema.pets.id, set: { clientId: uc.id, name: uc.petName, species: "Dog", breed: uc.petBreed, weightKg: "25.00", dateOfBirth: new Date("2021-03-15T00:00:00Z") } });
|
||||
.values({ id: uc.petId, clientId: uc.id, name: uc.petName, species: "Dog", breed: uc.petBreed, weightKg: "25.00", dateOfBirth: new Date("2021-03-15T00:00:00Z"), image: pick(demoPetImages) })
|
||||
.onConflictDoUpdate({ target: schema.pets.id, set: { clientId: uc.id, name: uc.petName, species: "Dog", breed: uc.petBreed, weightKg: "25.00", dateOfBirth: new Date("2021-03-15T00:00:00Z"), image: pick(demoPetImages) } });
|
||||
// Create one completed appointment for this client
|
||||
const apptId = uuid();
|
||||
const svcIdx = 0;
|
||||
|
||||
Reference in New Issue
Block a user