202 Commits

Author SHA1 Message Date
Fatih Kadir Akın dbe3bc707a Fix GitHub OAuth callback issuer validation 2026-09-09 13:24:46 +03:00
harichaudhary79900@gmail.com eaab6b14a0 Add prompt: School managment erp 2026-09-06 03:17:49 +00:00
dd3567523@gmail.com 845e5981c3 Add prompt: الإدارة الفعالة 2026-09-06 03:17:48 +00:00
kaskis7070@gmail.com 94f8f316af Add prompt: Sexycity 2026-09-06 03:17:48 +00:00
simonenespolosan@gmail.com e46fc4ff0e Add prompt: PRAETOR v7.1 – Privacy-First CV Self-Assessment System Prompt 2026-09-06 03:17:47 +00:00
hussen.sepa@gmail.com d84e95fc0e Add prompt: Enhanmcnet suggestion and analysis 2026-09-06 03:17:47 +00:00
oncehumsn0@gmail.com 8bb66f546d Update prompt: Anime 2026-09-06 03:17:46 +00:00
write2aniketsingh@gmail.com 5dba701ae5 Update prompt: Test 2026-09-06 03:17:46 +00:00
madhavbadaya@gmail.com b6a7d1646a Update prompt: Doctor 2026-09-06 03:17:46 +00:00
piyashossen11@gmail.com 7ed8d29aa8 Update prompt: Code Review Specialist 2026-09-06 03:17:45 +00:00
adediwuratemitope9-tech 91fcde5a2e Update prompt: Video 2026-09-06 03:17:45 +00:00
adediwuratemitope9-tech b7be86970b Update prompt: Lecturer 2026-09-06 03:17:44 +00:00
xiaoyucunx 8e85009ad1 Update prompt: Code Review Specialist 2026-09-06 03:17:44 +00:00
cperalesg@gmail.com b23360f0dd Update prompt: Prompt Generator 2026-09-06 03:17:43 +00:00
panda667 bac39d75f4 Update prompt: Astrologer 2026-09-06 03:17:42 +00:00
joembolinas 1b1da2a0d4 Update prompt: The Technical Co-Founder: Building Real Products Together 2026-09-06 03:17:42 +00:00
aymanrabeemac@gmail.com 838923cb14 Update prompt: Code Review Specialist 2026-09-06 03:17:41 +00:00
aitank2020@gmail.com 9f2c42867f Update prompt: Echoes of the Rust Age 2026-09-06 03:17:41 +00:00
dragoy18@gmail.com 0e116b9953 Update prompt: Code Review Specialist 2 2026-09-06 03:17:40 +00:00
lior1976@gmail.com 8b3edb2f69 Update prompt: Article Summarizer 2026-09-06 03:17:40 +00:00
beresasis@gmail.com fb78462eeb Update prompt: Interview Preparation Coach 2026-09-06 03:17:39 +00:00
sinansonmez 112fe9c247 Update prompt: Code Review Assistant 2026-09-06 03:17:39 +00:00
giorgiop 951c254bea Update prompt: Virtual Doctor 2026-09-06 03:17:38 +00:00
naiara.morillas@gmail.com 17ee1fd8ac Add prompt: DESAYUNO EN LA TEJICA 2026-09-05 03:16:56 +00:00
sb3232945@gmail.com 5dd5b05700 Add prompt: SaaPro Marketong 2026-09-05 03:16:55 +00:00
adediwuratemitope745@gmail.com 5d1ab876e1 Update prompt: Lecturer 2026-09-05 03:16:55 +00:00
itnesttomal@gmail.com ccf602ce13 Update prompt: Video 2026-09-05 03:16:54 +00:00
lokki29400@gmail.com 384701326b Update prompt: Anime 2026-09-05 03:16:54 +00:00
624406266@qq.com 12aeba2854 Update prompt: Code Review Specialist 2026-09-05 03:16:53 +00:00
xiaoyucunx 095aa0b298 Update prompt: Code Review Specialist 2026-09-05 03:16:53 +00:00
fede.gazzelloni@gmail.com af532289c6 Update prompt: Article Summarizer 2026-09-05 03:16:52 +00:00
debashis.sarker@gmail.com 078ef933e4 Update prompt: The Technical Co-Founder: Building Real Products Together 2026-09-05 03:16:52 +00:00
BuiltByPhil f20d8c36f3 Update prompt: Test 2026-09-05 03:16:51 +00:00
thanos0000@gmail.com 27dd78e36d Update prompt: Hallucination Vulnerability Prompt Checker 2026-09-05 03:16:51 +00:00
aymanrabeemac@gmail.com 4e1b7e61c1 Update prompt: Code Review Specialist 2026-09-05 03:16:50 +00:00
nolanneff bf3eebf267 Update prompt: Code Review Specialist 2 2026-09-05 03:16:50 +00:00
ersinkoc 0600cf5611 Update prompt: Echoes of the Rust Age 2026-09-05 03:16:49 +00:00
cnwdy888@gmail.com 2a5ad784aa Update prompt: Interview Preparation Coach 2026-09-05 03:16:48 +00:00
guangzhongzhang978@gmail.com ba29ddc9c0 Update prompt: Virtual Doctor 2026-09-05 03:16:48 +00:00
thanos0000@gmail.com 2a77c8b2c8 Update prompt: When to clear the snow (generic) 2026-09-05 03:16:47 +00:00
f 6efcdaac16 Update prompt: Code Review Assistant 2026-09-05 03:16:47 +00:00
devisasari 54cc5991b9 Update prompt: Astrologer 2026-09-05 03:16:46 +00:00
iuzn d2281ef4b3 Update prompt: Prompt Generator 2026-09-05 03:16:46 +00:00
devisasari 9dc504d3ee Update prompt: Doctor 2026-09-05 03:16:45 +00:00
tstaleburrahman@gmail.com 2d2d410e31 Add prompt: The fox 2026-09-04 03:17:53 +00:00
en.abdo2003@gmail.com b4a4fa223a Add prompt: حلول طابعة 2026-09-04 03:17:53 +00:00
aleenamayaa@gmail.com 9eca40ca7c Add prompt: Rainy Season College Moodboard - 6-Frame Scrapbook Collage 2026-09-04 03:17:52 +00:00
oncehumsn0@gmail.com 2c89f1ac4a Update prompt: Anime 2026-09-04 03:17:51 +00:00
write2aniketsingh@gmail.com 1b5a4f4881 Update prompt: Test 2026-09-04 03:17:51 +00:00
madhavbadaya@gmail.com b412371a15 Update prompt: Doctor 2026-09-04 03:17:51 +00:00
piyashossen11@gmail.com 0caef2a4b2 Update prompt: Code Review Specialist 2026-09-04 03:17:50 +00:00
adediwuratemitope9-tech d00bd44653 Update prompt: Video 2026-09-04 03:17:50 +00:00
adediwuratemitope9-tech 7e2e1b253c Update prompt: Lecturer 2026-09-04 03:17:49 +00:00
xiaoyucunx 33a0148e51 Update prompt: Code Review Specialist 2026-09-04 03:17:48 +00:00
cperalesg@gmail.com 88b6e804ce Update prompt: Prompt Generator 2026-09-04 03:17:48 +00:00
panda667 901d269050 Update prompt: Astrologer 2026-09-04 03:17:47 +00:00
joembolinas b8c1030095 Update prompt: The Technical Co-Founder: Building Real Products Together 2026-09-04 03:17:47 +00:00
aymanrabeemac@gmail.com f4a7a7a4c0 Update prompt: Code Review Specialist 2026-09-04 03:17:46 +00:00
aitank2020@gmail.com 496ccb7496 Update prompt: Echoes of the Rust Age 2026-09-04 03:17:46 +00:00
dragoy18@gmail.com 5e4a1ba4c9 Update prompt: Code Review Specialist 2 2026-09-04 03:17:45 +00:00
lior1976@gmail.com c9fdcfcdda Update prompt: Article Summarizer 2026-09-04 03:17:45 +00:00
beresasis@gmail.com 90272ab2c3 Update prompt: Interview Preparation Coach 2026-09-04 03:17:44 +00:00
sinansonmez 7f3032b4ee Update prompt: Code Review Assistant 2026-09-04 03:17:44 +00:00
giorgiop 4235f9cff6 Update prompt: Virtual Doctor 2026-09-04 03:17:43 +00:00
greenhushaoqi@gmail.com 414b71ae0b Add prompt: 分析股票亚康股份的走势 2026-09-03 04:30:24 +00:00
anjani.varsha2001@gmail.com df9a3413d9 Add prompt: assesment 2026-09-03 04:30:24 +00:00
slmtkomunitas@gmail.com af4cec26fb Add prompt: streaming anime 2026-09-03 04:30:23 +00:00
adediwuratemitope745@gmail.com 3180b786f8 Update prompt: Lecturer 2026-09-03 04:30:23 +00:00
itnesttomal@gmail.com 955ca36cb4 Update prompt: Video 2026-09-03 04:30:22 +00:00
lokki29400@gmail.com 66b9e0bd9e Update prompt: Anime 2026-09-03 04:30:22 +00:00
624406266@qq.com 555fcbc3fe Update prompt: Code Review Specialist 2026-09-03 04:30:21 +00:00
xiaoyucunx cdf3b252d8 Update prompt: Code Review Specialist 2026-09-03 04:30:21 +00:00
fede.gazzelloni@gmail.com 5748aeb23a Update prompt: Article Summarizer 2026-09-03 04:30:20 +00:00
debashis.sarker@gmail.com 1f911b8bdf Update prompt: The Technical Co-Founder: Building Real Products Together 2026-09-03 04:30:19 +00:00
BuiltByPhil 451ec5b63f Update prompt: Test 2026-09-03 04:30:19 +00:00
aymanrabeemac@gmail.com 21c700acc9 Update prompt: Code Review Specialist 2026-09-03 04:30:19 +00:00
nolanneff 4508f9575c Update prompt: Code Review Specialist 2 2026-09-03 04:30:18 +00:00
ersinkoc 0d75ea6995 Update prompt: Echoes of the Rust Age 2026-09-03 04:30:18 +00:00
cnwdy888@gmail.com 861a5cb20b Update prompt: Interview Preparation Coach 2026-09-03 04:30:17 +00:00
guangzhongzhang978@gmail.com 392e209153 Update prompt: Virtual Doctor 2026-09-03 04:30:17 +00:00
f 2224524146 Update prompt: Code Review Assistant 2026-09-03 04:30:16 +00:00
devisasari 07cb5c2e9c Update prompt: Astrologer 2026-09-03 04:30:16 +00:00
iuzn 266ae098c7 Update prompt: Prompt Generator 2026-09-03 04:30:15 +00:00
devisasari f0e0c0efbd Update prompt: Doctor 2026-09-03 04:30:15 +00:00
justmeormeandme@gmail.com 128192dff7 Add prompt: Abk 2026-09-02 03:17:52 +00:00
ashutosh02m.pro@gmail.com 7d04d0cead Add prompt: ExpertLens-Lite 2026-09-02 03:17:52 +00:00
vmmadaan51@gmail.com b623bdbbfb Add prompt: Code oprimisation / optimise your code 2026-09-02 03:17:51 +00:00
oncehumsn0@gmail.com a274b1831c Update prompt: Anime 2026-09-02 03:17:51 +00:00
write2aniketsingh@gmail.com a0169b2af9 Update prompt: Test 2026-09-02 03:17:50 +00:00
madhavbadaya@gmail.com b24b65893b Update prompt: Doctor 2026-09-02 03:17:50 +00:00
piyashossen11@gmail.com 450f5d274a Update prompt: Code Review Specialist 2026-09-02 03:17:50 +00:00
adediwuratemitope9-tech 479b607726 Update prompt: Video 2026-09-02 03:17:49 +00:00
adediwuratemitope9-tech 49d4d89d23 Update prompt: Lecturer 2026-09-02 03:17:49 +00:00
xiaoyucunx a023e114d5 Update prompt: Code Review Specialist 2026-09-02 03:17:48 +00:00
cperalesg@gmail.com e4435c3fb0 Update prompt: Prompt Generator 2026-09-02 03:17:48 +00:00
panda667 7affa4e4c0 Update prompt: Astrologer 2026-09-02 03:17:47 +00:00
joembolinas e17072878d Update prompt: The Technical Co-Founder: Building Real Products Together 2026-09-02 03:17:47 +00:00
aymanrabeemac@gmail.com c989304868 Update prompt: Code Review Specialist 2026-09-02 03:17:46 +00:00
aitank2020@gmail.com ba2a3265ae Update prompt: Echoes of the Rust Age 2026-09-02 03:17:46 +00:00
dragoy18@gmail.com 57b27327c2 Update prompt: Code Review Specialist 2 2026-09-02 03:17:45 +00:00
lior1976@gmail.com fc06885541 Update prompt: Article Summarizer 2026-09-02 03:17:45 +00:00
beresasis@gmail.com cfeeb61d51 Update prompt: Interview Preparation Coach 2026-09-02 03:17:45 +00:00
sinansonmez 1f16ad3dbd Update prompt: Code Review Assistant 2026-09-02 03:17:44 +00:00
giorgiop 5678aa4586 Update prompt: Virtual Doctor 2026-09-02 03:17:44 +00:00
manda.thetreesurgeon@gmail.com 50c4a5a1e7 Add prompt: Business management 2026-09-01 03:19:46 +00:00
researchairoot@gmail.com d1fdf222d9 Add prompt: exam science study notes 2026-09-01 03:19:46 +00:00
caosiyawen@gmail.com 1926094861 Add prompt: xiangxiang 2026-09-01 03:19:45 +00:00
islam.ataul@gmail.com b67516fb08 Add prompt: The curriculum mapping prompt. 2026-09-01 03:19:45 +00:00
adediwuratemitope745@gmail.com 8fb5c86021 Update prompt: Lecturer 2026-09-01 03:19:44 +00:00
itnesttomal@gmail.com 069b39ac35 Update prompt: Video 2026-09-01 03:19:44 +00:00
lokki29400@gmail.com 43668b3aa5 Update prompt: Anime 2026-09-01 03:19:43 +00:00
624406266@qq.com 623024a1f8 Update prompt: Code Review Specialist 2026-09-01 03:19:43 +00:00
xiaoyucunx 5dc319a5ec Update prompt: Code Review Specialist 2026-09-01 03:19:42 +00:00
fede.gazzelloni@gmail.com c1081e2a87 Update prompt: Article Summarizer 2026-09-01 03:19:42 +00:00
debashis.sarker@gmail.com cf48b03d88 Update prompt: The Technical Co-Founder: Building Real Products Together 2026-09-01 03:19:41 +00:00
BuiltByPhil 6ed3ba4910 Update prompt: Test 2026-09-01 03:19:41 +00:00
aymanrabeemac@gmail.com bc05cb7175 Update prompt: Code Review Specialist 2026-09-01 03:19:40 +00:00
nolanneff cbd014bdd7 Update prompt: Code Review Specialist 2 2026-09-01 03:19:40 +00:00
ersinkoc dc8a06edf8 Update prompt: Echoes of the Rust Age 2026-09-01 03:19:39 +00:00
cnwdy888@gmail.com 92defaf111 Update prompt: Interview Preparation Coach 2026-09-01 03:19:39 +00:00
guangzhongzhang978@gmail.com 99514cdbaf Update prompt: Virtual Doctor 2026-09-01 03:19:38 +00:00
f cd4894a002 Update prompt: Code Review Assistant 2026-09-01 03:19:38 +00:00
devisasari 7eea347638 Update prompt: Astrologer 2026-09-01 03:19:37 +00:00
iuzn 29ee983651 Update prompt: Prompt Generator 2026-09-01 03:19:37 +00:00
devisasari 7068c512fc Update prompt: Doctor 2026-09-01 03:19:36 +00:00
o99523198@gmail.com eb43a23641 Add prompt: Девушка футанари имеет парня 2026-08-31 03:19:20 +00:00
info@andujarmusic.com 9e50487605 Add prompt: Bariatric ADHD Supplement Safety Plan. 2026-08-31 03:19:20 +00:00
kennynah85@gmail.com a2648cc198 Add prompt: tweetwat 2026-08-31 03:19:19 +00:00
jerrysteifle@gmail.com 63fe8e647a Add prompt: Identify 2026-08-31 03:19:19 +00:00
a.alhashemali@gmail.com d6e63b0b1f Add prompt: GLP 2026-08-31 03:19:18 +00:00
oncehumsn0@gmail.com dfe4fb271e Update prompt: Anime 2026-08-31 03:19:18 +00:00
write2aniketsingh@gmail.com 7a583d77fd Update prompt: Test 2026-08-31 03:19:17 +00:00
madhavbadaya@gmail.com aa58dd4f6b Update prompt: Doctor 2026-08-31 03:19:17 +00:00
piyashossen11@gmail.com fb22290c07 Update prompt: Code Review Specialist 2026-08-31 03:19:17 +00:00
adediwuratemitope9-tech 5ef85ea7f4 Update prompt: Video 2026-08-31 03:19:16 +00:00
adediwuratemitope9-tech 300a045ef6 Update prompt: Lecturer 2026-08-31 03:19:16 +00:00
xiaoyucunx 2dd936b48e Update prompt: Code Review Specialist 2026-08-31 03:19:15 +00:00
cperalesg@gmail.com 3cfa103d43 Update prompt: Prompt Generator 2026-08-31 03:19:15 +00:00
panda667 465be358f6 Update prompt: Astrologer 2026-08-31 03:19:14 +00:00
joembolinas c5d1f6f143 Update prompt: The Technical Co-Founder: Building Real Products Together 2026-08-31 03:19:14 +00:00
aymanrabeemac@gmail.com c60e4d0cec Update prompt: Code Review Specialist 2026-08-31 03:19:13 +00:00
aitank2020@gmail.com 450c71c946 Update prompt: Echoes of the Rust Age 2026-08-31 03:19:13 +00:00
dragoy18@gmail.com e9649445ad Update prompt: Code Review Specialist 2 2026-08-31 03:19:12 +00:00
lior1976@gmail.com edff650f46 Update prompt: Article Summarizer 2026-08-31 03:19:12 +00:00
beresasis@gmail.com 55e52317ae Update prompt: Interview Preparation Coach 2026-08-31 03:19:11 +00:00
sinansonmez fbc9b78a3a Update prompt: Code Review Assistant 2026-08-31 03:19:11 +00:00
giorgiop fa5b387993 Update prompt: Virtual Doctor 2026-08-31 03:19:10 +00:00
sharanshakthii5@gmail.com 0b203286dd Add prompt: master one prompt 2026-08-30 03:17:32 +00:00
couragebillon@gmail.com e66527ea64 Add prompt: Little mann 2026-08-30 03:17:31 +00:00
couragebillon@gmail.com 857ed8304b Add prompt: Poor man 2026-08-30 03:17:31 +00:00
adediwuratemitope745@gmail.com a389c2b057 Update prompt: Lecturer 2026-08-30 03:17:31 +00:00
itnesttomal@gmail.com ecb85c0edd Update prompt: Video 2026-08-30 03:17:30 +00:00
lokki29400@gmail.com 106d56ec88 Update prompt: Anime 2026-08-30 03:17:29 +00:00
624406266@qq.com d321214fa3 Update prompt: Code Review Specialist 2026-08-30 03:17:29 +00:00
xiaoyucunx fa2a1bc5ac Update prompt: Code Review Specialist 2026-08-30 03:17:28 +00:00
fede.gazzelloni@gmail.com 15a33b4ba6 Update prompt: Article Summarizer 2026-08-30 03:17:28 +00:00
debashis.sarker@gmail.com 380f4debc9 Update prompt: The Technical Co-Founder: Building Real Products Together 2026-08-30 03:17:27 +00:00
BuiltByPhil 750576bd77 Update prompt: Test 2026-08-30 03:17:27 +00:00
aymanrabeemac@gmail.com e650f93fdc Update prompt: Code Review Specialist 2026-08-30 03:17:27 +00:00
nolanneff 4b39c48abc Update prompt: Code Review Specialist 2 2026-08-30 03:17:26 +00:00
ersinkoc 2fac6b73f0 Update prompt: Echoes of the Rust Age 2026-08-30 03:17:26 +00:00
cnwdy888@gmail.com 76ec700def Update prompt: Interview Preparation Coach 2026-08-30 03:17:25 +00:00
guangzhongzhang978@gmail.com 199a607dac Update prompt: Virtual Doctor 2026-08-30 03:17:25 +00:00
f 690402df4c Update prompt: Code Review Assistant 2026-08-30 03:17:24 +00:00
devisasari 5d075fb3fd Update prompt: Astrologer 2026-08-30 03:17:24 +00:00
iuzn 7bc358e458 Update prompt: Prompt Generator 2026-08-30 03:17:23 +00:00
devisasari 5652acc9e6 Update prompt: Doctor 2026-08-30 03:17:23 +00:00
raj.express2014@gmail.com 23ae8eb7d5 Add prompt: CV build 2026-08-29 03:15:55 +00:00
oncehumsn0@gmail.com b3e8cdefec Update prompt: Anime 2026-08-29 03:15:54 +00:00
write2aniketsingh@gmail.com e8d9faa5e1 Update prompt: Test 2026-08-29 03:15:54 +00:00
madhavbadaya@gmail.com 57b7e4e85e Update prompt: Doctor 2026-08-29 03:15:54 +00:00
piyashossen11@gmail.com 6a324fa85b Update prompt: Code Review Specialist 2026-08-29 03:15:53 +00:00
adediwuratemitope9-tech 50d06a54a1 Update prompt: Video 2026-08-29 03:15:53 +00:00
adediwuratemitope9-tech ffb23b3b75 Update prompt: Lecturer 2026-08-29 03:15:52 +00:00
xiaoyucunx 19d276b5ee Update prompt: Code Review Specialist 2026-08-29 03:15:52 +00:00
cperalesg@gmail.com 516ae5d574 Update prompt: Prompt Generator 2026-08-29 03:15:51 +00:00
panda667 dab6227074 Update prompt: Astrologer 2026-08-29 03:15:51 +00:00
joembolinas 68b73f99fb Update prompt: The Technical Co-Founder: Building Real Products Together 2026-08-29 03:15:50 +00:00
aymanrabeemac@gmail.com 0dd6df1d88 Update prompt: Code Review Specialist 2026-08-29 03:15:50 +00:00
aitank2020@gmail.com 8b22931c33 Update prompt: Echoes of the Rust Age 2026-08-29 03:15:49 +00:00
dragoy18@gmail.com 59bdb4b35c Update prompt: Code Review Specialist 2 2026-08-29 03:15:49 +00:00
lior1976@gmail.com a5f67df0f5 Update prompt: Article Summarizer 2026-08-29 03:15:49 +00:00
beresasis@gmail.com 5dd79322c0 Update prompt: Interview Preparation Coach 2026-08-29 03:15:48 +00:00
sinansonmez 10d54a6c8b Update prompt: Code Review Assistant 2026-08-29 03:15:48 +00:00
giorgiop 69f21f4ea6 Update prompt: Virtual Doctor 2026-08-29 03:15:47 +00:00
adediwuratemitope745@gmail.com c53a4f1e28 Update prompt: Lecturer 2026-08-28 05:47:14 +00:00
itnesttomal@gmail.com 0df0776a4c Update prompt: Video 2026-08-28 05:47:13 +00:00
lokki29400@gmail.com 197057f2f5 Update prompt: Anime 2026-08-28 05:47:13 +00:00
624406266@qq.com 89873f6a1b Update prompt: Code Review Specialist 2026-08-28 05:47:12 +00:00
xiaoyucunx 75d9a7c77a Update prompt: Code Review Specialist 2026-08-28 05:47:12 +00:00
fede.gazzelloni@gmail.com 411c817989 Update prompt: Article Summarizer 2026-08-28 05:47:11 +00:00
debashis.sarker@gmail.com 508b602d6e Update prompt: The Technical Co-Founder: Building Real Products Together 2026-08-28 05:47:11 +00:00
BuiltByPhil fc82c54298 Update prompt: Test 2026-08-28 05:47:10 +00:00
aymanrabeemac@gmail.com 616d379f7d Update prompt: Code Review Specialist 2026-08-28 05:47:10 +00:00
nolanneff ba1f39c70d Update prompt: Code Review Specialist 2 2026-08-28 05:47:09 +00:00
ersinkoc 0409f91f04 Update prompt: Echoes of the Rust Age 2026-08-28 05:47:09 +00:00
cnwdy888@gmail.com bc2c84def4 Update prompt: Interview Preparation Coach 2026-08-28 05:47:08 +00:00
guangzhongzhang978@gmail.com 6f22791329 Update prompt: Virtual Doctor 2026-08-28 05:47:08 +00:00
f 1590feb25e Update prompt: Code Review Assistant 2026-08-28 05:47:07 +00:00
devisasari 5d3ef708e1 Update prompt: Astrologer 2026-08-28 05:47:07 +00:00
iuzn 5906c55874 Update prompt: Prompt Generator 2026-08-28 05:47:06 +00:00
devisasari b4bc0a327e Update prompt: Doctor 2026-08-28 05:47:06 +00:00
6 changed files with 5048 additions and 336 deletions
+3 -2
View File
@@ -15,8 +15,8 @@ NEXTAUTH_SECRET="your-super-secret-key-change-in-production"
# AZURE_AD_CLIENT_ID=""
# AZURE_AD_CLIENT_SECRET=""
# AZURE_AD_TENANT_ID=""
# AUTH_GITHUB_ID=your_client_id
# AUTH_GITHUB_SECRET=your_client_secret
# GITHUB_CLIENT_ID=your_client_id
# GITHUB_CLIENT_SECRET=your_client_secret
# Run `npx auth add apple` to generate the secret, follow the instructions in the prompt
# AUTH_APPLE_ID=""
@@ -113,3 +113,4 @@ CRON_SECRET="your-secret-key-here"
# AUTH_OAUTH_JWKS_URL="https://sso.example.com/jwks"
# AUTH_OAUTH_TOKEN_AUTH_METHOD="client_secret_basic" # Allowed values: "client_secret_basic", "client_secret_post", "none"
# AUTH_OAUTH_ENABLE_PKCE="true" # PKCE is enabled by default. Set to "false" to disable.
+2648 -57
View File
File diff suppressed because it is too large Load Diff
+2298 -55
View File
File diff suppressed because it is too large Load Diff
+89 -117
View File
@@ -1,138 +1,110 @@
// @vitest-environment node
import { Auth, type AuthConfig } from "@auth/core";
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import type { GitHubProfile } from "next-auth/providers/github";
import type { OAuthConfig, OAuthUserConfig } from "next-auth/providers";
import { githubPlugin } from "@/lib/plugins/auth/github";
interface GitHubProviderOptions extends OAuthUserConfig<GitHubProfile> {
userinfo: {
request: (params: {
tokens: { access_token?: string };
}) => Promise<GitHubProfile>;
};
const ORIGIN = "https://prompts.test";
const GITHUB_ISSUER = "https://github.com/login/oauth";
function responseCookies(response: Response): string {
return response.headers.getSetCookie().map((cookie) => cookie.split(";")[0]).join("; ");
}
function getProviderOptions(): GitHubProviderOptions {
const provider = githubPlugin.getProvider() as OAuthConfig<GitHubProfile>;
return provider.options as GitHubProviderOptions;
}
function mockGitHubResponses(
emails: Array<{
email: string;
primary: boolean;
verified: boolean;
visibility: "public" | "private";
}>
) {
const fetchMock = vi
.fn<typeof fetch>()
.mockResolvedValueOnce(
new Response(
JSON.stringify({
id: 123,
login: "octocat",
name: "The Octocat",
email: null,
avatar_url: "https://avatars.githubusercontent.com/u/123",
}),
{ status: 200 }
)
)
.mockResolvedValueOnce(
new Response(JSON.stringify(emails), { status: 200 })
);
vi.stubGlobal("fetch", fetchMock);
return fetchMock;
}
describe("GitHub auth plugin", () => {
const originalEnv = process.env;
describe("GitHub OAuth callback", () => {
const fetchMock = vi.fn<typeof fetch>();
const signIn = vi.fn(() => true);
const logError = vi.fn();
let config: AuthConfig;
beforeEach(() => {
process.env = { ...originalEnv };
delete process.env.AUTH_GITHUB_ID;
delete process.env.AUTH_GITHUB_SECRET;
delete process.env.GITHUB_CLIENT_ID;
delete process.env.GITHUB_CLIENT_SECRET;
vi.stubEnv("GITHUB_CLIENT_ID", "test-github-client");
vi.stubEnv("GITHUB_CLIENT_SECRET", "test-github-secret");
vi.stubGlobal("fetch", fetchMock);
fetchMock.mockImplementation(async (input) => {
const url = String(input);
if (url === "https://github.com/login/oauth/access_token") {
return Response.json({ access_token: "test-access-token", token_type: "bearer" });
}
if (url === "https://api.github.com/user") {
return Response.json({
id: 123,
login: "testuser",
name: "Test User",
email: "test@example.com",
avatar_url: "https://avatars.githubusercontent.com/u/123",
});
}
throw new Error(`Unexpected fetch: ${url}`);
});
config = {
providers: [githubPlugin.getProvider()],
secret: "github-callback-test-secret",
trustHost: true,
basePath: "/api/auth",
callbacks: { signIn },
logger: { error: logError, warn: vi.fn(), debug: vi.fn() },
};
});
afterEach(() => {
process.env = originalEnv;
vi.unstubAllEnvs();
vi.unstubAllGlobals();
vi.clearAllMocks();
});
it("uses Auth.js GitHub credential names", () => {
process.env.AUTH_GITHUB_ID = "auth-client-id";
process.env.AUTH_GITHUB_SECRET = "auth-client-secret";
const options = getProviderOptions();
expect(options.clientId).toBe("auth-client-id");
expect(options.clientSecret).toBe("auth-client-secret");
});
it("supports legacy GitHub credential names", () => {
process.env.GITHUB_CLIENT_ID = "legacy-client-id";
process.env.GITHUB_CLIENT_SECRET = "legacy-client-secret";
const options = getProviderOptions();
expect(options.clientId).toBe("legacy-client-id");
expect(options.clientSecret).toBe("legacy-client-secret");
});
it("enables account linking only with a verified GitHub email", async () => {
const fetchMock = mockGitHubResponses([
{
email: "unverified@example.com",
primary: true,
verified: false,
visibility: "private",
async function startSignIn(): Promise<string> {
const csrfResponse = await Auth(new Request(`${ORIGIN}/api/auth/csrf`), config);
const { csrfToken } = await csrfResponse.json() as { csrfToken: string };
const response = await Auth(new Request(`${ORIGIN}/api/auth/signin/github`, {
method: "POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
Cookie: responseCookies(csrfResponse),
},
{
email: "verified@example.com",
primary: false,
verified: true,
visibility: "private",
},
]);
const options = getProviderOptions();
body: new URLSearchParams({ csrfToken, callbackUrl: ORIGIN }),
}), config);
const profile = await options.userinfo.request({
tokens: { access_token: "github-token" },
});
const authorizationUrl = new URL(response.headers.get("location")!);
expect(authorizationUrl.origin).toBe("https://github.com");
expect(authorizationUrl.searchParams.get("code_challenge_method")).toBe("S256");
expect(authorizationUrl.searchParams.get("code_challenge")).toBeTruthy();
return responseCookies(response);
}
expect(options.allowDangerousEmailAccountLinking).toBe(true);
expect(profile.email).toBe("verified@example.com");
expect(fetchMock).toHaveBeenCalledTimes(2);
expect(fetchMock).toHaveBeenCalledWith(
"https://api.github.com/user/emails",
expect.objectContaining({
headers: expect.objectContaining({
Authorization: "Bearer github-token",
}),
})
);
it.each([GITHUB_ISSUER, undefined])("accepts GitHub callbacks with issuer %s", async (issuer) => {
const cookies = await startSignIn();
const callbackUrl = new URL(`${ORIGIN}/api/auth/callback/github?code=test-code`);
if (issuer) callbackUrl.searchParams.set("iss", issuer);
const response = await Auth(new Request(callbackUrl, { headers: { Cookie: cookies } }), config);
expect(logError).not.toHaveBeenCalled();
expect(response.headers.get("location")).toBe(ORIGIN);
expect(signIn).toHaveBeenCalledWith(expect.objectContaining({
user: expect.objectContaining({ email: "test@example.com", username: "testuser" }),
account: expect.objectContaining({ provider: "github", providerAccountId: "123" }),
}));
expect(responseCookies(response)).toContain("__Secure-authjs.session-token=");
const tokenRequest = fetchMock.mock.calls.find(([url]) => String(url).endsWith("/access_token"));
expect((tokenRequest?.[1]?.body as URLSearchParams).get("code_verifier")).toBeTruthy();
});
it("rejects GitHub profiles without a verified email", async () => {
mockGitHubResponses([
{
email: "unverified@example.com",
primary: true,
verified: false,
visibility: "private",
},
]);
const options = getProviderOptions();
it("rejects a callback from an unexpected issuer before exchanging the code", async () => {
const cookies = await startSignIn();
const callbackUrl = new URL(`${ORIGIN}/api/auth/callback/github?code=test-code`);
callbackUrl.searchParams.set("iss", "https://unexpected.example.com");
await expect(
options.userinfo.request({
tokens: { access_token: "github-token" },
})
).rejects.toThrow(
"GitHub account does not have a verified email address"
);
const response = await Auth(new Request(callbackUrl, { headers: { Cookie: cookies } }), config);
expect(new URL(response.headers.get("location")!).searchParams.get("error")).toBe("Configuration");
expect(logError).toHaveBeenCalledWith(expect.objectContaining({
cause: expect.objectContaining({
err: expect.objectContaining({ message: 'unexpected "iss" (issuer) response parameter value' }),
}),
}));
expect(fetchMock).not.toHaveBeenCalled();
expect(signIn).not.toHaveBeenCalled();
expect(responseCookies(response)).not.toContain("authjs.session-token");
});
});
+2 -2
View File
@@ -236,11 +236,11 @@ export default async function SelfHostingPage() {
</TableHeader>
<TableBody>
<TableRow>
<TableCell className="font-mono text-xs">AUTH_GITHUB_ID</TableCell>
<TableCell className="font-mono text-xs">GITHUB_CLIENT_ID</TableCell>
<TableCell className="text-muted-foreground text-sm">GitHub OAuth App client ID</TableCell>
</TableRow>
<TableRow>
<TableCell className="font-mono text-xs">AUTH_GITHUB_SECRET</TableCell>
<TableCell className="font-mono text-xs">GITHUB_CLIENT_SECRET</TableCell>
<TableCell className="text-muted-foreground text-sm">GitHub OAuth App client secret</TableCell>
</TableRow>
<TableRow>
+8 -103
View File
@@ -1,109 +1,15 @@
import GitHub, {
type GitHubEmail,
type GitHubProfile,
} from "next-auth/providers/github";
import type { TokenSet } from "@auth/core/types";
import GitHub from "next-auth/providers/github";
import type { AuthPlugin } from "../types";
const GITHUB_API_URL = "https://api.github.com";
function isGitHubProfile(value: unknown): value is GitHubProfile {
if (!value || typeof value !== "object") return false;
const profile = value as Partial<GitHubProfile>;
return (
typeof profile.id === "number" &&
typeof profile.login === "string" &&
typeof profile.avatar_url === "string"
);
}
function isGitHubEmail(value: unknown): value is GitHubEmail {
if (!value || typeof value !== "object") return false;
const email = value as Partial<GitHubEmail>;
return (
typeof email.email === "string" &&
typeof email.primary === "boolean" &&
typeof email.verified === "boolean"
);
}
async function getVerifiedGitHubProfile(
accessToken: string
): Promise<GitHubProfile> {
const headers = {
Authorization: `Bearer ${accessToken}`,
Accept: "application/vnd.github+json",
"X-GitHub-Api-Version": "2022-11-28",
"User-Agent": "prompts.chat",
};
const [profileResponse, emailsResponse] = await Promise.all([
fetch(`${GITHUB_API_URL}/user`, { headers }),
fetch(`${GITHUB_API_URL}/user/emails`, { headers }),
]);
if (!profileResponse.ok) {
throw new Error(
`GitHub profile request failed with status ${profileResponse.status}`
);
}
if (!emailsResponse.ok) {
throw new Error(
`GitHub email request failed with status ${emailsResponse.status}`
);
}
const profile: unknown = await profileResponse.json();
const emails: unknown = await emailsResponse.json();
if (!isGitHubProfile(profile)) {
throw new Error("GitHub returned an invalid user profile");
}
if (!Array.isArray(emails)) {
throw new Error("GitHub returned an invalid email list");
}
const githubEmails = emails.filter(isGitHubEmail);
const verifiedEmail =
githubEmails.find((email) => email.primary && email.verified) ??
githubEmails.find((email) => email.verified);
if (!verifiedEmail) {
throw new Error("GitHub account does not have a verified email address");
}
return {
...profile,
email: verifiedEmail.email,
};
}
const githubUserinfo = {
url: `${GITHUB_API_URL}/user`,
async request({ tokens }: { tokens: TokenSet }) {
if (!tokens.access_token) {
throw new Error("GitHub did not return an access token");
}
return getVerifiedGitHubProfile(tokens.access_token);
},
};
export const githubPlugin: AuthPlugin = {
id: "github",
name: "GitHub",
getProvider: () => {
const clientId =
process.env.AUTH_GITHUB_ID || process.env.GITHUB_CLIENT_ID;
const clientSecret =
process.env.AUTH_GITHUB_SECRET || process.env.GITHUB_CLIENT_SECRET;
return GitHub({
clientId,
clientSecret,
allowDangerousEmailAccountLinking: true,
userinfo: githubUserinfo,
getProvider: () =>
GitHub({
// GitHub includes this issuer in OAuth authorization responses.
issuer: "https://github.com/login/oauth",
clientId: process.env.GITHUB_CLIENT_ID!,
clientSecret: process.env.GITHUB_CLIENT_SECRET!,
profile(profile) {
return {
id: profile.id.toString(),
@@ -114,6 +20,5 @@ export const githubPlugin: AuthPlugin = {
githubUsername: profile.login, // Immutable GitHub username for contributor attribution
};
},
});
},
}),
};