@easy-cms/core 0.61.0 → 0.63.0

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.
@@ -1169,11 +1169,13 @@ function safeEqual(a, b) {
1169
1169
  const right = Buffer.from(b);
1170
1170
  return left.length === right.length && timingSafeEqual4(left, right);
1171
1171
  }
1172
- function signPreviewToken(secret, target, expiresAt) {
1172
+ function signPreviewToken(secret, target, expiresAt, user) {
1173
1173
  const payload = Buffer.from(
1174
- JSON.stringify(
1175
- "global" in target ? { g: target.global, e: expiresAt } : { c: target.collection, i: target.id, e: expiresAt }
1176
- )
1174
+ JSON.stringify({
1175
+ ..."global" in target ? { g: target.global } : { c: target.collection, i: target.id },
1176
+ e: expiresAt,
1177
+ ...user !== void 0 ? { u: user } : {}
1178
+ })
1177
1179
  ).toString("base64url");
1178
1180
  return `${payload}.${hmac(secret, `preview:${payload}`)}`;
1179
1181
  }
@@ -1185,9 +1187,10 @@ function verifyPreviewToken(secret, token, now = Date.now()) {
1185
1187
  try {
1186
1188
  const data = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
1187
1189
  if (typeof data.e !== "number" || data.e <= now) return null;
1188
- if (typeof data.g === "string") return { global: data.g, expiresAt: data.e };
1190
+ const user = typeof data.u === "string" ? { user: data.u } : {};
1191
+ if (typeof data.g === "string") return { global: data.g, expiresAt: data.e, ...user };
1189
1192
  if (typeof data.c === "string" && typeof data.i === "string")
1190
- return { collection: data.c, id: data.i, expiresAt: data.e };
1193
+ return { collection: data.c, id: data.i, expiresAt: data.e, ...user };
1191
1194
  return null;
1192
1195
  } catch {
1193
1196
  return null;
@@ -1723,7 +1726,14 @@ var Auth = class {
1723
1726
  ...args.name ? { name: args.name } : {}
1724
1727
  });
1725
1728
  const raw = await this.db.findById({ collection: USERS, id: user.id });
1726
- return this.startSession(raw);
1729
+ const session = await this.startSession(raw);
1730
+ await this.cms.audit.record({
1731
+ action: "setup",
1732
+ target: "auth",
1733
+ user: session.user,
1734
+ detail: { setupCode: !!code }
1735
+ });
1736
+ return session;
1727
1737
  }
1728
1738
  // --- Members signing up (`auth.members.signUp`) ---------------------------------------------
1729
1739
  /** What a sign-up form needs: a token proving when it was loaded, and Turnstile's site key. */
@@ -1927,6 +1937,12 @@ var Auth = class {
1927
1937
  if (!user || user.active === false) return null;
1928
1938
  return this.toAuthUser(user);
1929
1939
  }
1940
+ /** An active user by id, as requests see them; `null` when deleted or deactivated. @internal */
1941
+ async activeUser(id) {
1942
+ const user = await this.db.findById({ collection: USERS, id });
1943
+ if (!user || user.active === false) return null;
1944
+ return this.toAuthUser(user);
1945
+ }
1930
1946
  /** The CSRF token clients must echo for a signed session token. @internal */
1931
1947
  csrfFor(signedToken) {
1932
1948
  const token = unsignToken(this.config.secret, signedToken);
@@ -4612,6 +4628,7 @@ function validateConfig(config) {
4612
4628
  return issues;
4613
4629
  }
4614
4630
  validateSecret(config.secret, add);
4631
+ validateCronSecret(config.cronSecret, (issue) => issues.push(issue));
4615
4632
  checkConfigKeys(config, (issue) => issues.push(issue));
4616
4633
  validateAdapterVersions(config, add);
4617
4634
  if (!config.db || typeof config.db.name !== "string" || typeof config.db.init !== "function") {
@@ -4687,6 +4704,27 @@ function validateSecret(secret, add) {
4687
4704
  add("secret", "looks like an example or a repeated pattern, not a random string", hint);
4688
4705
  }
4689
4706
  }
4707
+ function validateCronSecret(value, push) {
4708
+ const hint = `use a random string of at least ${MIN_SECRET_LENGTH} characters, e.g. \`openssl rand -hex 32\``;
4709
+ if (value !== void 0) {
4710
+ if (typeof value !== "string") push({ path: "cronSecret", message: "must be a string" });
4711
+ else if (value.length < MIN_SECRET_LENGTH)
4712
+ push({
4713
+ path: "cronSecret",
4714
+ message: `must be at least ${MIN_SECRET_LENGTH} characters (got ${value.length})`,
4715
+ hint
4716
+ });
4717
+ return;
4718
+ }
4719
+ const env = process.env.CRON_SECRET;
4720
+ if (env && env.length < MIN_SECRET_LENGTH)
4721
+ push({
4722
+ path: "cronSecret",
4723
+ message: `CRON_SECRET is ${env.length} characters; anyone who guesses it can run jobs`,
4724
+ hint,
4725
+ severity: "warning"
4726
+ });
4727
+ }
4690
4728
  function guessable(secret) {
4691
4729
  return /change[-_ ]?me|example|placeholder|secret-?key/i.test(secret) || new Set(secret).size < 8;
4692
4730
  }
@@ -6021,6 +6059,221 @@ function resolveAudit(audit) {
6021
6059
  // src/local-api.ts
6022
6060
  import { createHmac as createHmac6, randomBytes as randomBytes5, timingSafeEqual as timingSafeEqual5 } from "crypto";
6023
6061
 
6062
+ // src/auth/common-passwords.ts
6063
+ var LIST = `
6064
+ 0.0.0.000 01234567 063dyjuy 085tzzqi 09876543 10101010 11001001 11111111 11112222 11223344
6065
+ 11235813 12121212 12312312 123123123 12341234 12344321 12345678 123456789 1234567890 12345679
6066
+ 1234abcd 1234qwer 12locked 12qwaszx 13131313 13576479 14141414 14725836 14789632 151nxjmt
6067
+ 154ugeiu 17011701 17171717 18436572 19691969 19741974 19781978 19841984 1a2b3c4d 1letmein
6068
+ 1michael 1million 1passwor 1q2w3e4r 1q2w3e4r5t 1qaz2wsx 1qazxsw2 1x2zkg8w 20002000 20012001
6069
+ 201jedlz 20202020 20spanks 21122112 21212121 22222222 23232323 23skidoo 24242424 24682468
6070
+ 25252525 25802580 31415926 33333333 368ejhih 380zliki 383pdjvl 44444444 474jdvff 50spanks
6071
+ 51505150 551scasi 554uzpad 55555555 55bgates 5wr2i7h8 66666666 66668888 69696969 69camaro
6072
+ 766rglqy 77777777 78945612 863abgsg 87654321 88888888 8j4ye3uz 911turbo 98765432 987654321
6073
+ 99999999 a1234567 a1b2c3d4 aaaaaaa1 aaaaaaaa aardvark abc12345 abcd1234 abcdefg1 abcdefgh
6074
+ aberdeen abnormal absolute absolutely acapulco access14 access99 achilles acidburn adelaide
6075
+ adrienne aerosmit airborne aircraft airforce airplane albatros alejandr alessand alexalex
6076
+ alexande alexander alexandr alexandra alfarome alleycat alliance allison1 allnight allstate
6077
+ almighty alpha123 alphabet amateurs amatuers ambrosia america1 american amethyst amsterda
6078
+ amsterdam anaconda anastasi andersen anderson andromed andyandy andyod22 angelica angelika
6079
+ angelina animated annabell annmarie antelope anthony1 anthony7 anything aolsucks apollo13
6080
+ apple123 applepie aquarius archange architec argentin arizona1 arkansas armstron arsenal1
6081
+ asdf1234 asdfasdf asdfghjk asdfghjkl ashleigh assassin asshole1 assholes atlantic atlantis
6082
+ atreides attitude attorney auckland augustus austin31 australi australia avalanch aviation
6083
+ azertyui b929ezzh baberuth babybaby babyblue babycake babydoll babyface babygirl babylon5
6084
+ babylove backbone backdoor badabing balloons baltimor bangbang barbados barcelon barcelona
6085
+ barefeet barefoot baritone basebal1 baseball baseball1 basement basketba basketball bastards
6086
+ bbbbbbbb bcfields bearbear bearcats beatles1 beatrice beautifu beautiful beefcake beerbeer
6087
+ beethove bellagio bendover benjamin bergkamp berkeley bettyboo bigballs bigblack bigblock
6088
+ bigboobs bigbooty bigbucks bigdaddy bigdick1 bigdicks bigmoney bigpenis bigpoppa bigtruck
6089
+ billabon billbill billybob billyboy binladen birthday birthday1 birthday4 bitchass blackbir
6090
+ blackcat blackcoc blackdog blackhaw blackice blackjac blackjack blacklab blackman blackout
6091
+ blessing blink182 blizzard blowfish blue1234 blueball bluebell blueberr bluebird blueblue
6092
+ blueeyes bluefish bluejays bluemoon bluesman bobafett bobdylan bollocks bonehead bookworm
6093
+ borabora bordeaux borussia bradford brandon1 brewster brighton brigitte brisbane brittany
6094
+ brittney broadway broncos1 brooklyn brothers browning brucelee bubba123 bubbles1 buckaroo
6095
+ buckeyes buckshot budapest buddy123 buddyboy budlight budweise buffalo1 building bukowski
6096
+ bulldawg bulldog1 bulldogs bulletin bullfrog bullseye bullshit bullwink bunghole business
6097
+ businessbabe buttercu butterfl butterfly buttfuck butthead butthole cabernet cadillac caldwell
6098
+ calendar caliente californ california caligula calimero callaway callisto camaross cambridg
6099
+ cameltoe cameron1 campbell canadian candyass candyman cannabis capetown capitals capricor
6100
+ capslock captain1 cardinal cardinals care1839 carebear carlitos carnival carolina caroline
6101
+ carpedie carpente cartman1 cartoons casanova cashflow cashmone cassandr castillo catalina
6102
+ catfight catherin catherine catwoman cavalier cbr900rr cccccccc celebrity cerberus cezer121
6103
+ chadwick chainsaw challeng chambers champion chandler changeme chargers charisma charlene
6104
+ charles1 charlie1 charlie123 charlie2 charlott charlotte charlton checkers checkmat cheerleaers
6105
+ chelsea1 chemical cherokee cherries cheshire chester1 chestnut chevelle chevrole chevrolet
6106
+ chewbacc cheyenne chicago1 chicken1 chickens children chipmunk chiquita chocolat chocolate
6107
+ choochoo chris123 chrisbln christia christian christie christin christina christine christma
6108
+ christmas christop christopher chrysler chuckles churchil cinnamon citation civilwar clarence
6109
+ clarinet clarissa classics claudia1 claymore clemente cleopatr clevelan cleveland clifford
6110
+ climbing clippers clitoris close-up clueless cocacola cocksuck cocksucker cocktail coldbeer
6111
+ coldplay colombia colonial colorado coltrane columbia columbus comanche commande commando
6112
+ complete computer concorde concrete confused conquest constant consumer contains contortionist
6113
+ contract coolcool cooldude coolhand coolness copenhag corleone cornhole cornwall corvet07
6114
+ corvette costello cosworth courtney coventry cowboys1 crawford crazybab crazyman creampie
6115
+ creation creative creature creepers crescent cricket1 criminal cristian cristina cromwell
6116
+ crusader crystal1 csfbr5yy culinary customer cutiepie cybersex cyclones cygnusx1 dad2ownu
6117
+ daedalus daisydog danielle dannyboy dapzu455 daredevi darkange darklord darkness darkside
6118
+ darkstar darthvad daughter davecole davedave davidson daylight dddddddd deadhead deadpool
6119
+ deadspin death666 december deepthroat deerhunt deeznuts deeznutz defender deftones delaware
6120
+ delldell delpiero designer destiny1 detectiv devil666 devildog devilman diamond1 diamonds
6121
+ dickdick dickhead dietcoke digital1 dilbert1 dilligaf dingdong dinosaur dipstick director
6122
+ dirtbike dirtydog disaster discover division doberman dodgeram dodgers1 doghouse dogpound
6123
+ dolemite dolphin1 dolphins dominick dominion dominiqu dontknow doomsday doughboy doughnut
6124
+ downhill downtown dragon12 dragon69 dragonba dragonball dragonfl dragster dreamcas dreamer1
6125
+ dreaming dripping drowssap drpepper drummer1 dudedude dukeduke dutchess dynamite earnhard
6126
+ earthlin earthlink eastside eastwood eatmenow eatpussy eclipse1 edgewise edmonton eeeeeeee
6127
+ eggplant eighteen einstein ejaculation elcamino eldiablo eldorado electric electron elephant
6128
+ elisabet elizabet elizabeth embalmer emmanuel enforcer engineer england1 enternow enterpri
6129
+ enterprise entrance envelope erection ericsson escalade espresso estrella eternity evangeli
6130
+ everlast evolutio excalibu excalibur exchange experience experienced explorer express1 f00tball
6131
+ fairlane faithful fandango fantasia fantasies farscape fastball fatluvr69 favorite favorite2
6132
+ favorite6 fearless feathers february federico feelgood fellatio ferguson fernando ferrari1
6133
+ festival ffffffff ffvdj474 fidelity fighting films+pic+galeries fingerig fireball fireblad
6134
+ firefigh firefire firehawk firewall fishbone fishcake fisherma fishfish fishhead fishing1
6135
+ fishtank flamingo flanders flashman flathead fletcher flexible flipflop flipmode florence
6136
+ florida1 flounder flyers88 football football1 fordf150 foreplay foreskin forgetit formula1
6137
+ forsaken fortress fortune12 fountain foxylady francesc francine francois frankie1 franklin
6138
+ freckles frederic fredfred fredrick freedom1 freefall freefree freepass freeporn freeuser
6139
+ freewill frenchie friendly frogfrog front242 frontier fuck_inside fuckface fuckfuck fuckhead
6140
+ fuckinside fuckoff1 fuckthis fuckyou1 fuckyou2 fullback fullmoon funstuff funtimes fussball
6141
+ fuzzball gabriel1 gabriela gabriell galeries gallaries gamecock gamecube gameover gandalf1
6142
+ gangbang gangbanged gangster garfield gargoyle garrison gateway1 gateway2 gatorade general1
6143
+ generals genesis1 geneviev geoffrey gerhardt geronimo gertrude gesperrt getmoney getsdown
6144
+ gfxqx686 gggggggg gilligan ginscoot giovanna giovanni girfriend giuseppe giveitup gizmodo1
6145
+ gladiato gladiator glendale glennwei gnasher23 godfathe godfather godsmack godspeed godzilla
6146
+ gogators goldberg goldeney goldfing goldfish goldstar goldwing golfball golfgolf gonzales
6147
+ gonzalez goodfell goodgirl goodluck goodtime goodyear goofball gooseman gordon24 gorgeous
6148
+ gotohell gotyoass graduate graphics grateful graywolf greatest greatone green123 greenbay
6149
+ greenday greenman gregory1 gretchen greywolf griffith gsxr1000 guardian guinness gymnastic
6150
+ hahahaha hairball halflife hallowee hamilton handball handsome handyman hannibal happines
6151
+ happy123 happyday happydog happyman hardball hardcock hardcore harddick hardrock hardware
6152
+ hardwood harrison hartford hastings hattrick hawaii50 hawaiian hawkeyes hawkwind hawthorn
6153
+ hayabusa heather1 hedgehog heineken heinrich hellfire hello123 hellohel hellyeah hercules
6154
+ herewego heritage hetfield hhhhhhhh highbury highheel highland highlander highlife hihje863
6155
+ hillbill hillside holidays hollywoo hollywood holyshit homemade homepage homepage- honeybee
6156
+ honeydew hongkong honolulu hooligan hoosiers hooters1 hopeless hornyman horseman horsemen
6157
+ hotgirls hotmail0 hotmail1 hotpussy hotstuff hounddog housewife housewifes houston1 hugetits
6158
+ hugohugo humphrey hurrican hurricane huskers1 hyperion hzze929b ibilltes icecream icehouse
6159
+ idontkno idontknow ihateyou iiiiiiii illinois illmatic illusion ilovegod ilovesex iloveyou
6160
+ iloveyou! iloveyou1 iloveyou2 immortal imperial implants infantry infinite infiniti infinity
6161
+ innocent insanity insertion insertions insomnia inspiron instinct interacial intercourse
6162
+ interest internal internet intrepid intruder iqzzt580 irishman isabella isabelle isacs155
6163
+ islander istanbul istheman italiano iverson3 jackass1 jackjack jackson1 jackson5 jakejake
6164
+ james007 jamesbon jamesbond japanees japanese jasmine1 jayhawks jeanette jediknig jeepjeep
6165
+ jeepster jefferso jeffjeff jellybea jennifer jennings jeremiah jermaine jessica1 jiggaman
6166
+ jjjjjjjj jo9k2jw2 johannes johndeer johngalt johnjohn johnmish johnson1 johnston jojojojo
6167
+ jonathan jonathon jordan23 josephin joystick juliette junkmail jupiter1 jupiter2 jurassic
6168
+ just4fun justdoit juventus kamikaze kangaroo katarina katherin katherine kathleen kawasaki
6169
+ kayleigh kcchiefs kcj9wx5n kentucky kenworth keyboard keystone kikimora killbill killkill
6170
+ kimberly kingfish kingkong kingrich kingston kirkland kisskiss kittycat kittykat kkkkkkkk
6171
+ klondike knickerless knickers knockers knuckles kordell1 kristian kristin1 kristina kristine
6172
+ labrador lacrosse laetitia lakeside lakewood lalakers lalalala lancelot landmark laserjet
6173
+ lasvegas laughing laurence lavalamp lawrence lebowski leedsutd lemonade leonardo lesbians
6174
+ letmein1 letmein2 letmein22 letmeinn letmesee letsdoit lexingky lifehack lifetime lighthou
6175
+ lighting lightnin lightning limewire lincoln1 lionhear lionking lipstick lisalisa littlema
6176
+ liverpoo liverpool lkjhgfds llllllll lockdown lockerroom logitech lollipop lollypop lonesome
6177
+ lonestar lonewolf longdong longhair longhorn longjohn longshot lorraine losangel lovelife
6178
+ lovelove loverboy loverman lowrider luckydog luckyone lunchbox luv2epus macaroni macdaddy
6179
+ macgyver macintos madeline madison1 magazine magellan magician magicman magnolia mainland
6180
+ majestic makaveli mallorca mallrats mamacita manchest manchester mandarin mandingo mandrake
6181
+ manhatta maradona marathon marauder marcello marcius2 margaret marianne marijuan mariners
6182
+ marines1 marino13 mariposa marjorie marlboro marriage marshall martinez maryjane maryland
6183
+ masamune maserati mash4077 master12 masterbaiting masterbate masterbating masturbation matchbox
6184
+ material matthew1 matthews matthias maverick maxwell1 mazda626 mazdarx7 mccarthy mcdonald
6185
+ mckenzie meatball meathead meatloaf mechanic medicine megadeth megapass megatron melanie1
6186
+ melissa1 meowmeow mephisto mercedes merchant mercury1 meredith meridian metallic metallica
6187
+ michael1 michael2 michaela michaels michelle michigan microsof microsoft midnight mikemike
6188
+ milamber military millions millwall minemine minimoni ministry minnesot mischief misfit99
6189
+ mississi missouri mistress mitchell mmmmmmmm mobydick modelsne mohammad mohammed mollydog
6190
+ monalisa money123 moneyman mongoose monkey12 monkeybo monopoly monster1 monsters montana1
6191
+ montecar monterey montreal montrose moonbeam moonligh moonlight moonshin morpheus morrison
6192
+ mortgage morticia mortimer motherfucker motocros motorola mounta1n mountain mudvayne muffdive
6193
+ mulligan munchkin mushroom musician musicman mustang1 mustang2 mustang5 mustang6 mustangs
6194
+ mwq6qlzo myspace1 myxworld nancy123 napoleon nascar24 natalie1 natasha1 natedogg nathalie
6195
+ nathanie national navyseal ncc1701a ncc1701d ncc1701e ncc74656 nebraska necklace negative
6196
+ nemrac58 netscape nevermin newcastl newcastle newpass6 newyork1 nicetits nicholas nightmar
6197
+ nightowl nightwin nineball nineinch nineteen nintendo nirvana1 nnnnnnnn nocturne nonenone
6198
+ normandy northern nostromo notebook notredam nounours november novifarm nwo4life nygiants
6199
+ nyyankee oblivion obsidian offshore oklahoma oooooooo opendoor operator optimist original
6200
+ outoutout outsider overkill overlord ozlq6qwm pa55w0rd pa55word packers1 paintbal paintball
6201
+ painting pakistan paladin1 pallmall palmtree panasoni panasonic pantera1 panther1 panthers
6202
+ papabear papillon paradigm paradise paramedi paranoid pasadena pass1234 passmast passpass
6203
+ passport passthie passw0rd passwor1 password password1 password2 password9 passwords passwort
6204
+ patches1 pathetic pathfind patience patricia patrick1 patriots paulpaul pavement pavilion
6205
+ peaches1 pearljam peekaboo penelope penetrating penetration penguin1 penguins pennywis pentagon
6206
+ penthous perfect1 personal pertinant pescator peterbil peternorth peterpan peterson phaedrus
6207
+ phantom1 pharmacy phialpha philippe phillies phillips phoenix1 pianoman pictuers piercing
6208
+ pimpdadd pimpdaddy pineappl pinetree pingpong pinkfloy pinkfloyd pinnacle pipeline pitchers
6209
+ pizzaman plastics platinum platypus playball playboy1 playboy2 playmate playoffs playstat
6210
+ playstation playtime pleasant pleasure plymouth polopolo poohbear pool6123 poontang poophead
6211
+ pooppoop porkchop porn4life pornking pornographic pornporn porsche1 porsche9 portland portugal
6212
+ poseidon positive postov1000 pounding pppppppp preacher precious predator pregnant prelude1
6213
+ presario presiden president pressure primetime21 princess princeto pringles printing private1
6214
+ producer progress property prophecy prospect ptfe3xxp pumpkin1 pumpkins punisher punkrock
6215
+ puppydog pussy123 pussy4me pussycat pussyeat pussyman pxx3eftp q1w2e3r4 qazwsxed qazwsxedc
6216
+ qcmfd454 qqqqqqqq quant4307s question qwer1234 qwerasdf qwerqwer qwert123 qwerty12 qwerty123
6217
+ qwertyui qwertyuiop qwertzui r2d2c3po rachelle radiohea ragnarok raiders1 railroad rainbow1
6218
+ rainbow6 rainbows rainyday raistlin randolph rangers1 rapunzel rasputin rasta220 rebecca1
6219
+ reckless recovery redalert redbaron reddevil reddwarf redheads redlight redshift redskins
6220
+ redstorm redwings reginald register reindeer remember remingto renegade republic research
6221
+ resident revoluti revolver reynolds rhiannon richard1 richards richmond riffraff rightnow
6222
+ riverrat riversid roadkill roadking roadrunn roadster robinson robotech robotics rochelle
6223
+ rockford rockhard rocknrol rockrock rockstar rockwell rolltide rootbeer rootedit rosemary
6224
+ rrrrrrrr rsalinas rt6ytere rush2112 rushmore russell1 rustydog sabrina1 sailboat salasana
6225
+ salesman salvador samadams samantha samsung1 sandberg sandiego sandrine sandwich sanity72
6226
+ santiago sapphire saratoga satan666 saturday sausages savannah save13tx saxophon scandinavian
6227
+ scarface scarlett scheisse scirocco scissors scoobydo scoobydoo scooter1 scorpio1 scorpion
6228
+ scotland scrabble scrapper screamer screwyou seahawks sealteam sebastia sebastian security
6229
+ seductive seinfeld seminole semperfi senators sentinel sentnece septembe september serenity
6230
+ sergeant services sexsexsex sexybabe sexygirl sexylady sexysexy shadow12 shamrock shanghai
6231
+ shannon1 sheepdog shepherd sheridan sherlock sherwood shitface shithead shitshit shopping
6232
+ showtime sickness sidekick sigmachi silverad simpsons sinclair singapor sinister sithlord
6233
+ sixtynin skeeter1 skinhead skipper1 skittles skydiver skywalke skywalker slamdunk slapnuts
6234
+ slapshot sleeping slimed123 slimshad slipknot slippery slowhand smackdow smartass smashing
6235
+ smeghead smirnoff smithers smoothie snapshot sneakers snickers sniffing snoopdog snowball
6236
+ snowbird snowboar snowboard snowflak snuggles soccer10 soccer11 soccer12 socrates softball
6237
+ softtail software solitude solution somerset somethin something sometime sonyfuck sonysony
6238
+ sooners1 sopranos soulmate southern southpar southpark southpaw spaceman spanking sparhawk
6239
+ sparkles spartan1 spartans speakers special1 specialk spectrum speedway spencer1 spiderma
6240
+ spiderman spitfire splinter spongebo sporting springer sprinter sprocket squerting squirrel
6241
+ srinivas ssptx452 ssssssss stafford stallion standard stanford stanley1 starbuck starcraf
6242
+ starcraft stardust starfire starfish stargate starligh starlite starship starstar startrek
6243
+ starwars steelers stefanie stephane stephani stephanie stephen1 stephens sterling stewart1
6244
+ stickman stiletto stingray stirling stocking stockton stonecol stonecold stonewal stoppedby
6245
+ straight stranger strawber streaming strength stripper suburban success1 suckcock suckdick
6246
+ sullivan summer69 summer99 sundance sundevil sunflowe sunlight sunnyday sunshine superfly
6247
+ superior superman supernov supersta superstar surprise surveyor survival survivor svetlana
6248
+ sweetnes sweetness sweetpea swimming swingers swinging swordfis swordfish sylveste syracuse
6249
+ tacobell tailgate takehana talisman tampabay tangerin tarheels tazmania technics techniques
6250
+ teddybea telephon temppass temptress tennesse terminal terminat terrapin test1234 testerer
6251
+ testibil testing1 testpass testtest thailand thanatos thankyou thedoors theforce thegreat
6252
+ thematri theodore therock1 thething thetruth thinking thirteen thisisit thompson thrasher
6253
+ threesom thriller thuglife thumbnils thumper1 thunder1 thunderb thursday tiberius tickling
6254
+ ticklish tiffany1 tiger123 tigercat tinkerbe titanium titleist tmjxn151 together tomahawk
6255
+ tommyboy tomorrow toonarmy toriamos tottenha tottenham touching trailers training transexual
6256
+ transfer traveler treasure treefrog triangle trinidad trinitro trinity1 trombone trooper1
6257
+ tropical trouble1 troubles trousers trucking trueblue truelove trumpet1 trustno1 tttttttt
6258
+ tunafish turkey50 twilight ultimate umbrella unbelievable uncencored underdog undertak
6259
+ undertaker undertow underwear universa universe university ursitesux username usmarine uuuuuuuu
6260
+ vacation vagabond valdepen valencia valentin valhalla valkyrie valleywa vampire1 vampires
6261
+ vancouve vanessa1 vanguard vanhalen vauxhall velocity verbatim veronica veronika verygood
6262
+ victoria viewsoni vikings1 vincent1 violator vipergts virginia virginie vivitron vladimir
6263
+ volkswag volleyba voyager1 vvvvvvvv wanderer wapapapa warcraft wareagle warhamme warrior1
6264
+ warriors washburn washingt washington watching waterboy waterfal waterloo waterman waterski
6265
+ webmaste webmaster wednesda wednesday welcome1 wellingt werewolf westside westwood wetpussy
6266
+ wg8e3wjf whatever whatwhat whiplash whiskers whistler whiteboy whiteout whitesox whocares
6267
+ wildbill wildcard wildcats wildfire wildstar wildwood william1 williams windmill windows1
6268
+ windsurf winfield wingchun winston1 winter99 wireless wishbone wolfgang wolfpack wolverin
6269
+ wolverine wonderboy wonderfu woodland woodstoc woodwork woofwoof wordpass wp2003wp wrangler
6270
+ wrestler wrestlin wrestling wrinkle1 wrinkle5 wwwwwwww xxxxxxx1 xxxxxxxx yamahar1 yankees1
6271
+ yankees2 yeahbaby yeahyeah year2005 yesterda yogibear yosemite yqlgr667 yvtte545 yy5rbfsc
6272
+ yyyyyyyy zachary1 zanzibar zaq12wsx zaq1xsw2 zeppelin zerocool zildjian zoomzoom zxcvbnm1
6273
+ zzzzzzzz
6274
+ `;
6275
+ var COMMON_PASSWORDS = new Set(LIST.split(/\s+/).filter(Boolean));
6276
+
6024
6277
  // src/localization.ts
6025
6278
  var ALL_LOCALES = "all";
6026
6279
  var isPlainObject2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -6374,6 +6627,10 @@ async function createEasyCMS(config, options = {}) {
6374
6627
  const cms = new EasyCMS(resolved3, db, logger, storage, cwd);
6375
6628
  const scheduling = [...resolved3.collections, ...resolved3.globals].some((c) => c.schedule) || (resolved3.webhooks?.length ?? 0) > 0 || resolved3.email !== void 0 || resolved3.jobs.length > 0;
6376
6629
  if (scheduling && options.scheduler !== false) cms.startScheduler();
6630
+ if (process.env.NODE_ENV === "production" && !resolved3.auth.setupCode && await cms.auth.hasUsers().catch(() => true) === false)
6631
+ logger.warn(
6632
+ "No admin exists yet and no setup code is set: whoever opens the admin first becomes the admin. Set EASY_CMS_SETUP_CODE, or create the admin with `easy-cms admin:create`."
6633
+ );
6377
6634
  return cms;
6378
6635
  }
6379
6636
  var toJob = (row) => ({
@@ -6871,18 +7128,23 @@ var EasyCMS = class {
6871
7128
  }
6872
7129
  /**
6873
7130
  * How many documents use any of these files in a top-level upload field (rich text and fields
6874
- * inside groups, arrays and blocks are not counted). Drafts count too.
7131
+ * inside groups, arrays and blocks are not counted). Drafts count too. With
7132
+ * `overrideAccess: false`, only documents the user may read.
6875
7133
  */
6876
- async mediaUsage(ids) {
7134
+ async mediaUsage(ids, options = {}) {
6877
7135
  if (ids.length === 0) return 0;
6878
7136
  let count = 0;
6879
7137
  for (const config of this.config.collections) {
6880
7138
  if (INTERNAL_COLLECTIONS.has(config.slug)) continue;
6881
7139
  for (const field of config.fields) {
6882
7140
  if (field.type !== "upload") continue;
6883
- count += await this.db.count({
6884
- collection: config.slug,
6885
- where: { [field.name]: { in: [...ids] } }
7141
+ count += await this.count(config.slug, {
7142
+ ...options,
7143
+ where: { [field.name]: { in: [...ids] } },
7144
+ draft: true
7145
+ }).catch((error) => {
7146
+ if (error instanceof ForbiddenError || error instanceof UnauthorizedError) return 0;
7147
+ throw error;
6886
7148
  });
6887
7149
  }
6888
7150
  }
@@ -7133,12 +7395,15 @@ var EasyCMS = class {
7133
7395
  /**
7134
7396
  * A token that lets a page read one document's current draft for a while (default one hour),
7135
7397
  * without a login: `GET /api/cms/:collection/:id?preview=<token>`. The admin adds one to the
7136
- * preview URL as `easy-cms-preview`, for sites on another origin.
7398
+ * preview URL as `easy-cms-preview`, for sites on another origin. With `user`, the page reads
7399
+ * it with that user's access (fields they can't read are left out; a deactivated user's token
7400
+ * stops working); without, with full access.
7137
7401
  */
7138
7402
  createPreviewToken(target, options = {}) {
7139
7403
  const seconds = options.expiresIn ?? 60 * 60;
7140
7404
  const normalized = "global" in target ? target : { collection: target.collection, id: String(target.id) };
7141
- return signPreviewToken(this.config.secret, normalized, Date.now() + seconds * 1e3);
7405
+ const user = options.user ? String(options.user.id) : void 0;
7406
+ return signPreviewToken(this.config.secret, normalized, Date.now() + seconds * 1e3, user);
7142
7407
  }
7143
7408
  /** What a preview token opens, or `null` when it is invalid or expired. */
7144
7409
  verifyPreviewToken(token) {
@@ -7598,7 +7863,8 @@ var EasyCMS = class {
7598
7863
  const check3 = (operation) => this.checkDocumentAccess(config, operation, guard, parsed, void 0).then(
7599
7864
  () => true,
7600
7865
  (error) => {
7601
- if (error instanceof ForbiddenError || error instanceof UnauthorizedError) return false;
7866
+ if (error instanceof ForbiddenError || error instanceof UnauthorizedError || error instanceof NotFoundError)
7867
+ return false;
7602
7868
  throw error;
7603
7869
  }
7604
7870
  );
@@ -8067,7 +8333,38 @@ var EasyCMS = class {
8067
8333
  await this.checkQueryFields(config, guard, where);
8068
8334
  return andWhere(andWhere(where, access), own);
8069
8335
  }
8336
+ /**
8337
+ * Throws unless the caller may update or delete this document. A user who may not even read
8338
+ * it gets `NotFoundError`, as for an id that doesn't exist: a 403 would tell it does.
8339
+ */
8070
8340
  async checkDocumentAccess(config, operation, guard, id, data) {
8341
+ await this.hidingDenied(
8342
+ config.slug,
8343
+ guard,
8344
+ id,
8345
+ () => this.documentAccess(config, operation, guard, id, data)
8346
+ );
8347
+ }
8348
+ /** Runs a check; a `ForbiddenError` for a document the user can't read becomes a 404. */
8349
+ async hidingDenied(collection2, guard, id, check3) {
8350
+ try {
8351
+ await check3();
8352
+ } catch (error) {
8353
+ if (error instanceof ForbiddenError && !await this.mayRead(collection2, guard, id))
8354
+ throw new NotFoundError(collection2, String(id));
8355
+ throw error;
8356
+ }
8357
+ }
8358
+ async mayRead(collection2, guard, id) {
8359
+ const config = this.collection(collection2);
8360
+ try {
8361
+ const where = await this.readWhere(config, guard, { id: { equals: id } });
8362
+ return await this.db.count({ collection: collection2, where }) > 0;
8363
+ } catch {
8364
+ return false;
8365
+ }
8366
+ }
8367
+ async documentAccess(config, operation, guard, id, data) {
8071
8368
  if (!guard.enforce) return;
8072
8369
  const own = await this.checkGrant(guard, { collection: config.slug }, operation);
8073
8370
  const allowed2 = await evaluateAccess(config.access?.[operation], {
@@ -8134,13 +8431,15 @@ var EasyCMS = class {
8134
8431
  }
8135
8432
  /** `checkGrant` for one document: a role limited to its own documents must own it. */
8136
8433
  async checkDocumentGrant(guard, collection2, operation, id) {
8137
- const own = await this.checkGrant(guard, { collection: collection2 }, operation);
8138
- if (own === true) return;
8139
- const matches2 = await this.db.count({
8140
- collection: collection2,
8141
- where: andWhere(own, { id: { equals: id } })
8434
+ await this.hidingDenied(collection2, guard, id, async () => {
8435
+ const own = await this.checkGrant(guard, { collection: collection2 }, operation);
8436
+ if (own === true) return;
8437
+ const matches2 = await this.db.count({
8438
+ collection: collection2,
8439
+ where: andWhere(own, { id: { equals: id } })
8440
+ });
8441
+ if (matches2 === 0) throw deny(guard.user);
8142
8442
  });
8143
- if (matches2 === 0) throw deny(guard.user);
8144
8443
  }
8145
8444
  /** Runs afterRead hooks, populates relationships and removes what the caller may not see. */
8146
8445
  async output(config, docs, guard, options) {
@@ -8713,6 +9012,11 @@ function splitPassword(config, raw) {
8713
9012
  { field: "password", message: `must be at least ${MIN_PASSWORD_LENGTH} characters` }
8714
9013
  ]);
8715
9014
  }
9015
+ if (COMMON_PASSWORDS.has(password.normalize("NFKC").toLowerCase())) {
9016
+ throw new ValidationError(USERS, [
9017
+ { field: "password", message: "is one of the most common passwords; choose another" }
9018
+ ]);
9019
+ }
8716
9020
  return { input, password };
8717
9021
  }
8718
9022
  function asObject(data, name) {
@@ -8789,7 +9093,7 @@ async function readAdminModule(cms, index) {
8789
9093
  }
8790
9094
 
8791
9095
  // src/version.ts
8792
- var VERSION = true ? "0.61.0" : "0.0.0-dev";
9096
+ var VERSION = true ? "0.63.0" : "0.0.0-dev";
8793
9097
 
8794
9098
  // src/rest/admin-deliveries.ts
8795
9099
  var PER_PAGE = 50;
@@ -10033,6 +10337,7 @@ async function route(cms, ctx, method, path, options) {
10033
10337
  if (!byCron && !isSystemAdmin(ctx.user)) {
10034
10338
  throw ctx.user ? new HttpError("Forbidden", 403) : new UnauthorizedError();
10035
10339
  }
10340
+ if (!byCron && ctx.via === "cookie" && method !== "POST") throw methodNotAllowed(ctx, "POST");
10036
10341
  return { body: await cms.runJobs() };
10037
10342
  }
10038
10343
  if (first === "admin" && second === "backups") {
@@ -10152,7 +10457,12 @@ async function route(cms, ctx, method, path, options) {
10152
10457
  if (!ctx.user || ctx.user.apiKey) throw new UnauthorizedError();
10153
10458
  if (method !== "GET") throw methodNotAllowed(ctx, "GET");
10154
10459
  const ids = (ctx.url.searchParams.get("ids") ?? "").split(",").map((id2) => parseId(id2)).filter((id2) => id2 !== void 0);
10155
- return { body: { count: await cms.mediaUsage(ids) } };
10460
+ const count = await cms.mediaUsage(ids, {
10461
+ overrideAccess: false,
10462
+ user: ctx.user,
10463
+ context: ctx.context
10464
+ });
10465
+ return { body: { count } };
10156
10466
  }
10157
10467
  if (first === "admin" && second === "roles") {
10158
10468
  if (!ctx.user) throw new UnauthorizedError();
@@ -10297,9 +10607,10 @@ async function route(cms, ctx, method, path, options) {
10297
10607
  if (third !== void 0) return globalAction(cms, ctx, method, second, segments.slice(2));
10298
10608
  if (method === "GET") {
10299
10609
  if (ctx.url.searchParams.has("preview")) {
10300
- requirePreview(cms, ctx, { global: second });
10610
+ const as = await requirePreview(cms, ctx, { global: second });
10301
10611
  return {
10302
10612
  body: await cms.findGlobal(second, {
10613
+ ...as,
10303
10614
  ...parseDepth(ctx.url),
10304
10615
  ...parseLocale(ctx.url),
10305
10616
  draft: true
@@ -10408,8 +10719,9 @@ async function route(cms, ctx, method, path, options) {
10408
10719
  }
10409
10720
  const id = second;
10410
10721
  if (method === "GET" && ctx.url.searchParams.has("preview")) {
10411
- requirePreview(cms, ctx, { collection: collection2, id });
10722
+ const as = await requirePreview(cms, ctx, { collection: collection2, id });
10412
10723
  const doc = await cms.findById(collection2, id, {
10724
+ ...as,
10413
10725
  ...parseDepth(ctx.url),
10414
10726
  ...parseLocale(ctx.url),
10415
10727
  draft: true
@@ -10488,7 +10800,7 @@ async function documentAction(cms, ctx, method, collection2, id, path) {
10488
10800
  if (method !== "POST") throw methodNotAllowed(ctx, "POST");
10489
10801
  const body = await readJson(ctx.request);
10490
10802
  const result = await cms.preview(collection2, id, body, { ...access, ...depth });
10491
- const token = cms.createPreviewToken({ collection: collection2, id });
10803
+ const token = cms.createPreviewToken({ collection: collection2, id }, { user: ctx.user });
10492
10804
  return { body: { ...result, url: result.url && withPreviewToken(result.url, token) } };
10493
10805
  }
10494
10806
  if (path.length === 1 && (action === "unpublish" || action === "discard-draft")) {
@@ -10538,7 +10850,7 @@ async function globalAction(cms, ctx, method, slug2, path) {
10538
10850
  if (method !== "POST") throw methodNotAllowed(ctx, "POST");
10539
10851
  const body = await readJson(ctx.request);
10540
10852
  const result = await cms.previewGlobal(slug2, body, { ...access, ...depth });
10541
- const token = cms.createPreviewToken({ global: slug2 });
10853
+ const token = cms.createPreviewToken({ global: slug2 }, { user: ctx.user });
10542
10854
  return { body: { ...result, url: result.url && withPreviewToken(result.url, token) } };
10543
10855
  }
10544
10856
  if (path.length === 1 && (action === "unpublish" || action === "discard-draft")) {
@@ -10577,10 +10889,16 @@ function withPreviewToken(url, token) {
10577
10889
  const separator = base.includes("?") ? "&" : "?";
10578
10890
  return `${base}${separator}${PREVIEW_PARAM}=${encodeURIComponent(token)}${fragment}`;
10579
10891
  }
10580
- function requirePreview(cms, ctx, target) {
10892
+ async function requirePreview(cms, ctx, target) {
10581
10893
  const opened = cms.verifyPreviewToken(ctx.url.searchParams.get("preview"));
10582
10894
  const matches2 = opened !== null && ("global" in target ? "global" in opened && opened.global === target.global : "collection" in opened && opened.collection === target.collection && opened.id === target.id);
10583
10895
  if (!matches2) throw new UnauthorizedError("Invalid or expired preview token");
10896
+ if (opened.user === void 0) return {};
10897
+ const id = parseId(opened.user);
10898
+ const issuer = id === void 0 ? null : await cms.auth.activeUser(id);
10899
+ if (!issuer) throw new UnauthorizedError("Invalid or expired preview token");
10900
+ const { user, context } = await cms.applyOnRequest(ctx.request.headers, ctx.url, issuer);
10901
+ return { overrideAccess: false, user, context };
10584
10902
  }
10585
10903
  function parsePage(url) {
10586
10904
  const { page, limit } = parseListQuery(url);
@@ -1746,9 +1746,10 @@ declare class EasyCMS<C extends Config = Config> {
1746
1746
  private mediaSignature;
1747
1747
  /**
1748
1748
  * How many documents use any of these files in a top-level upload field (rich text and fields
1749
- * inside groups, arrays and blocks are not counted). Drafts count too.
1749
+ * inside groups, arrays and blocks are not counted). Drafts count too. With
1750
+ * `overrideAccess: false`, only documents the user may read.
1750
1751
  */
1751
- mediaUsage(ids: readonly ID[]): Promise<number>;
1752
+ mediaUsage(ids: readonly ID[], options?: AccessOptions): Promise<number>;
1752
1753
  /** The storage for public files, or for private ones. */
1753
1754
  storageFor(isPrivate: boolean): StorageAdapter;
1754
1755
  /**
@@ -1811,7 +1812,9 @@ declare class EasyCMS<C extends Config = Config> {
1811
1812
  /**
1812
1813
  * A token that lets a page read one document's current draft for a while (default one hour),
1813
1814
  * without a login: `GET /api/cms/:collection/:id?preview=<token>`. The admin adds one to the
1814
- * preview URL as `easy-cms-preview`, for sites on another origin.
1815
+ * preview URL as `easy-cms-preview`, for sites on another origin. With `user`, the page reads
1816
+ * it with that user's access (fields they can't read are left out; a deactivated user's token
1817
+ * stops working); without, with full access.
1815
1818
  */
1816
1819
  createPreviewToken(target: {
1817
1820
  collection: string;
@@ -1820,10 +1823,12 @@ declare class EasyCMS<C extends Config = Config> {
1820
1823
  global: string;
1821
1824
  }, options?: {
1822
1825
  expiresIn?: number;
1826
+ user?: AuthUser | null;
1823
1827
  }): string;
1824
1828
  /** What a preview token opens, or `null` when it is invalid or expired. */
1825
1829
  verifyPreviewToken(token: string | null | undefined): (PreviewTarget & {
1826
1830
  expiresAt: number;
1831
+ user?: string;
1827
1832
  }) | null;
1828
1833
  /** Live preview of a global. See `preview`. */
1829
1834
  previewGlobal<S extends GSlug<C>>(slug: S, data: Record<string, unknown>, options?: DepthOptions): Promise<LivePreview<GDoc<C, S>>>;
@@ -1992,7 +1997,15 @@ declare class EasyCMS<C extends Config = Config> {
1992
1997
  private checkGrant;
1993
1998
  /** The query constraint read access adds, or `undefined` when there is none. Throws when denied. */
1994
1999
  private readWhere;
2000
+ /**
2001
+ * Throws unless the caller may update or delete this document. A user who may not even read
2002
+ * it gets `NotFoundError`, as for an id that doesn't exist: a 403 would tell it does.
2003
+ */
1995
2004
  private checkDocumentAccess;
2005
+ /** Runs a check; a `ForbiddenError` for a document the user can't read becomes a 404. */
2006
+ private hidingDenied;
2007
+ private mayRead;
2008
+ private documentAccess;
1996
2009
  private checkGlobalAccess;
1997
2010
  private fieldChecker;
1998
2011
  /**
@@ -1,4 +1,4 @@
1
- import { I as ID, ab as Config, au as EasyCMS, bd as LocalizationConfig, aD as Field, aH as FieldError, aS as FilterOptions, af as CreateEasyCMSOptions, bI as ResolvedConfig } from './config-jzFGsNL6.js';
1
+ import { I as ID, ab as Config, au as EasyCMS, bd as LocalizationConfig, aD as Field, aH as FieldError, aS as FilterOptions, af as CreateEasyCMSOptions, bI as ResolvedConfig } from './config-Dgs6FE0S.js';
2
2
 
3
3
  type BackupState = 'pending' | 'running' | 'done' | 'failed';
4
4
  /** One backup as the admin shows it (`GET <api>/admin/backups`). */
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { P as PaginatedDocs, I as ID, E as EmailSetting } from './config-jzFGsNL6.js';
2
- export { A as ADAPTER_API_VERSION, a as ADMIN_ICONS, b as Access, c as AccessArgs, d as AccessOptions, e as AdminBrand, f as AdminCommand, g as AdminComponent, h as AdminConfig, i as AdminFieldArgs, j as AdminIcon, k as AdminLocale, l as AdminPage, m as AdminRole, n as AdminRoleChange, o as AdminRoleField, p as AdminRoleTarget, q as AdminRoleView, r as AdminRoles, s as AdminSso, t as AdminSwitcher, u as AdminViewAccess, v as AfterChangeHook, w as AfterDeleteHook, x as AfterReadHook, y as ApiKeyContext, z as ApiKeyGlobalOperation, B as ApiKeyOperation, C as ApiKeyPermissions, D as ArrayField, F as AuditChange, G as AuditConfig, H as AuditEntry, J as AuditLog, K as AuditPage, L as AuditVerification, M as Auth, N as AuthConfig, O as AuthProvider, Q as AuthProviderProfile, R as AuthProviderRequest, S as AuthUser, T as BackupsConfig, U as BeforeChangeHook, V as BeforeDeleteHook, W as BeforeValidateHook, X as Block, Y as BlocksField, Z as BooleanField, _ as BuiltinApiKeysCollection, $ as BuiltinMediaCollection, a0 as BuiltinMediaFoldersCollection, a1 as BuiltinUsersCollection, a2 as BundleHints, a3 as CliCommand, a4 as CollectionAccess, a5 as CollectionAdmin, a6 as CollectionConfig, a7 as CollectionDocument, a8 as CollectionHooks, a9 as CollectionListAdmin, aa as CollectionSlug, ab as Config, ac as ConfigError, ad as ConfigIssue, ae as ContainerAdmin, af as CreateEasyCMSOptions, ag as CreateInput, ah as CreateMigrationResult, ai as CustomField, aj as CustomFieldTypes, ak as DashboardWidget, al as Database, am as DatabaseAdapter, an as DatabaseInitArgs, ao as DatabaseTransfer, ap as DateField, aq as DepthOptions, ar as DirectUpload, as as DiskStorageOptions, at as DocumentOf, au as EasyCMS, av as EasyCMSError, aw as EmailAdapter, ax as EmailField, ay as EmailMessage, az as Endpoint, aA as EndpointRequest, aB as ErrorCode, aC as FIELD_TYPES, aD as Field, aE as FieldAccess, aF as FieldAccessFn, aG as FieldAdmin, aH as FieldError, aI as FieldRule, aJ as FieldType, aK as FieldTypeBase, aL as FieldTypeDefinition, aM as FieldTypeValidateContext, aN as FieldValidate, aO as FieldValidateContext, aP as FieldValue, aQ as FieldsInput, aR as FieldsValue, aS as FilterOptions, aT as FilterOptionsArgs, aU as FindArgs, aV as FindOptions, aW as FolderLevel, aX as FolderPermissions, aY as ForbiddenError, aZ as GlobalAccess, a_ as GlobalConfig, a$ as GlobalDocument, b0 as GlobalHooks, b1 as GlobalInput, b2 as GlobalSlug, b3 as GroupField, b4 as ImageSize, b5 as IncrementOptions, b6 as InferCollection, b7 as InferGlobal, b8 as JobConfig, b9 as JsonField, ba as Label, bb as LayoutNode, bc as LivePreview, bd as LocalizationConfig, be as Logger, bf as LoginArgs, bg as MediaDocument, bh as MediaSize, bi as MembersConfig, bj as MembersSignup, bk as MigrationInfo, bl as NavGroup, bm as NotFoundError, bn as NumberField, bo as OnRequest, bp as OnRequestArgs, bq as Operation, br as PLUGIN_API_VERSION, bs as PasswordEmail, bt as PasswordEmailArgs, bu as PasswordEmailFn, bv as PasswordLinkOptions, bw as PayloadTooLargeError, bx as Plugin, by as PluginInfo, bz as PluginTypes, bA as PreviewTarget, bB as PreviewURL, bC as QueryError, bD as ROLE_OPERATIONS, bE as RawDocument, bF as ReadOptions, bG as RelationshipField, bH as RequestContext, bI as ResolvedConfig, bJ as RichTextDocument, bK as RichTextField, bL as Role, bM as RoleOperation, bN as RolePermissions, bO as Roles, bP as RoutesConfig, bQ as ScheduledPublish, bR as SchemaError, bS as SchemaMode, bT as SelectField, bU as SelectOption, bV as Session, bW as SidebarPanel, bX as SignupArgs, bY as SignupResult, bZ as SingleSignOn, b_ as SlugField, b$ as SlugOf, c0 as SsoOutcome, c1 as SsoProviderRef, c2 as StorageAdapter, c3 as StoredFile, c4 as TextField, c5 as TextareaField, c6 as TooManyRequestsError, c7 as TypedPlugin, c8 as UnauthorizedError, c9 as UpdateInput, ca as UpdateOptions, cb as UploadConfig, cc as UploadField, cd as UploadFromURLConfig, ce as UserIdentity, cf as ValidationError, cg as Version, ch as VersionSummary, ci as VersionsConfig, cj as WEBHOOK_EVENTS, ck as WebhookConfig, cl as WebhookEvent, cm as WebhookPayload, cn as Where, co as WhereOperators, cp as anyone, cq as consoleEmail, cr as consoleLogger, cs as createEasyCMS, ct as defineConfig, cu as defineFieldType, cv as definePlugin, cw as diskStorage, cx as hasRows, cy as isAdmin, cz as isHasMany, cA as isSignedIn, cB as isStaff, cC as isSystemAdmin, cD as mimeAllowedBy, cE as rowFields, cF as silentLogger, cG as uniqueWithinOf } from './config-jzFGsNL6.js';
3
- export { A as ADMIN_API_VERSION, a as AdminCollection, b as AdminComponentRef, c as AdminElementProps, d as AdminField, e as AdminGlobal, f as AdminLayoutNode, g as AdminNavGroup, h as AdminNavItem, i as AdminNavNode, j as AdminPageRef, k as AdminPageRoute, l as AdminSchema, m as AdminWidgetRef, S as SetFieldDetail, w as warnDeprecated } from './plugin-C19Bt8ux.js';
4
- export { A as AdminBackup, a as AdminBackups, b as ApiHandlerOptions, B as BackupState, L as LoadConfigOptions, R as RestHandler, c as RestHandlerOptions, d as createApiHandler, e as createRestHandler, l as loadConfig, r as resolveConfig, s as sharedEasyCMS, f as slugify } from './handler-CMA1LIq7.js';
1
+ import { P as PaginatedDocs, I as ID, E as EmailSetting } from './config-Dgs6FE0S.js';
2
+ export { A as ADAPTER_API_VERSION, a as ADMIN_ICONS, b as Access, c as AccessArgs, d as AccessOptions, e as AdminBrand, f as AdminCommand, g as AdminComponent, h as AdminConfig, i as AdminFieldArgs, j as AdminIcon, k as AdminLocale, l as AdminPage, m as AdminRole, n as AdminRoleChange, o as AdminRoleField, p as AdminRoleTarget, q as AdminRoleView, r as AdminRoles, s as AdminSso, t as AdminSwitcher, u as AdminViewAccess, v as AfterChangeHook, w as AfterDeleteHook, x as AfterReadHook, y as ApiKeyContext, z as ApiKeyGlobalOperation, B as ApiKeyOperation, C as ApiKeyPermissions, D as ArrayField, F as AuditChange, G as AuditConfig, H as AuditEntry, J as AuditLog, K as AuditPage, L as AuditVerification, M as Auth, N as AuthConfig, O as AuthProvider, Q as AuthProviderProfile, R as AuthProviderRequest, S as AuthUser, T as BackupsConfig, U as BeforeChangeHook, V as BeforeDeleteHook, W as BeforeValidateHook, X as Block, Y as BlocksField, Z as BooleanField, _ as BuiltinApiKeysCollection, $ as BuiltinMediaCollection, a0 as BuiltinMediaFoldersCollection, a1 as BuiltinUsersCollection, a2 as BundleHints, a3 as CliCommand, a4 as CollectionAccess, a5 as CollectionAdmin, a6 as CollectionConfig, a7 as CollectionDocument, a8 as CollectionHooks, a9 as CollectionListAdmin, aa as CollectionSlug, ab as Config, ac as ConfigError, ad as ConfigIssue, ae as ContainerAdmin, af as CreateEasyCMSOptions, ag as CreateInput, ah as CreateMigrationResult, ai as CustomField, aj as CustomFieldTypes, ak as DashboardWidget, al as Database, am as DatabaseAdapter, an as DatabaseInitArgs, ao as DatabaseTransfer, ap as DateField, aq as DepthOptions, ar as DirectUpload, as as DiskStorageOptions, at as DocumentOf, au as EasyCMS, av as EasyCMSError, aw as EmailAdapter, ax as EmailField, ay as EmailMessage, az as Endpoint, aA as EndpointRequest, aB as ErrorCode, aC as FIELD_TYPES, aD as Field, aE as FieldAccess, aF as FieldAccessFn, aG as FieldAdmin, aH as FieldError, aI as FieldRule, aJ as FieldType, aK as FieldTypeBase, aL as FieldTypeDefinition, aM as FieldTypeValidateContext, aN as FieldValidate, aO as FieldValidateContext, aP as FieldValue, aQ as FieldsInput, aR as FieldsValue, aS as FilterOptions, aT as FilterOptionsArgs, aU as FindArgs, aV as FindOptions, aW as FolderLevel, aX as FolderPermissions, aY as ForbiddenError, aZ as GlobalAccess, a_ as GlobalConfig, a$ as GlobalDocument, b0 as GlobalHooks, b1 as GlobalInput, b2 as GlobalSlug, b3 as GroupField, b4 as ImageSize, b5 as IncrementOptions, b6 as InferCollection, b7 as InferGlobal, b8 as JobConfig, b9 as JsonField, ba as Label, bb as LayoutNode, bc as LivePreview, bd as LocalizationConfig, be as Logger, bf as LoginArgs, bg as MediaDocument, bh as MediaSize, bi as MembersConfig, bj as MembersSignup, bk as MigrationInfo, bl as NavGroup, bm as NotFoundError, bn as NumberField, bo as OnRequest, bp as OnRequestArgs, bq as Operation, br as PLUGIN_API_VERSION, bs as PasswordEmail, bt as PasswordEmailArgs, bu as PasswordEmailFn, bv as PasswordLinkOptions, bw as PayloadTooLargeError, bx as Plugin, by as PluginInfo, bz as PluginTypes, bA as PreviewTarget, bB as PreviewURL, bC as QueryError, bD as ROLE_OPERATIONS, bE as RawDocument, bF as ReadOptions, bG as RelationshipField, bH as RequestContext, bI as ResolvedConfig, bJ as RichTextDocument, bK as RichTextField, bL as Role, bM as RoleOperation, bN as RolePermissions, bO as Roles, bP as RoutesConfig, bQ as ScheduledPublish, bR as SchemaError, bS as SchemaMode, bT as SelectField, bU as SelectOption, bV as Session, bW as SidebarPanel, bX as SignupArgs, bY as SignupResult, bZ as SingleSignOn, b_ as SlugField, b$ as SlugOf, c0 as SsoOutcome, c1 as SsoProviderRef, c2 as StorageAdapter, c3 as StoredFile, c4 as TextField, c5 as TextareaField, c6 as TooManyRequestsError, c7 as TypedPlugin, c8 as UnauthorizedError, c9 as UpdateInput, ca as UpdateOptions, cb as UploadConfig, cc as UploadField, cd as UploadFromURLConfig, ce as UserIdentity, cf as ValidationError, cg as Version, ch as VersionSummary, ci as VersionsConfig, cj as WEBHOOK_EVENTS, ck as WebhookConfig, cl as WebhookEvent, cm as WebhookPayload, cn as Where, co as WhereOperators, cp as anyone, cq as consoleEmail, cr as consoleLogger, cs as createEasyCMS, ct as defineConfig, cu as defineFieldType, cv as definePlugin, cw as diskStorage, cx as hasRows, cy as isAdmin, cz as isHasMany, cA as isSignedIn, cB as isStaff, cC as isSystemAdmin, cD as mimeAllowedBy, cE as rowFields, cF as silentLogger, cG as uniqueWithinOf } from './config-Dgs6FE0S.js';
3
+ export { A as ADMIN_API_VERSION, a as AdminCollection, b as AdminComponentRef, c as AdminElementProps, d as AdminField, e as AdminGlobal, f as AdminLayoutNode, g as AdminNavGroup, h as AdminNavItem, i as AdminNavNode, j as AdminPageRef, k as AdminPageRoute, l as AdminSchema, m as AdminWidgetRef, S as SetFieldDetail, w as warnDeprecated } from './plugin-8hrkYMuR.js';
4
+ export { A as AdminBackup, a as AdminBackups, b as ApiHandlerOptions, B as BackupState, L as LoadConfigOptions, R as RestHandler, c as RestHandlerOptions, d as createApiHandler, e as createRestHandler, l as loadConfig, r as resolveConfig, s as sharedEasyCMS, f as slugify } from './handler-CcQjkj5Q.js';
5
5
  export { FieldCondition, matchesCondition } from './conditions.js';
6
6
 
7
7
  type DeliveryKind = 'webhook' | 'email';
package/dist/index.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  sharedEasyCMS,
24
24
  silentLogger,
25
25
  slugify
26
- } from "./chunk-HTE5O3EG.js";
26
+ } from "./chunk-LN4M4BUP.js";
27
27
  import {
28
28
  matchesCondition
29
29
  } from "./chunk-U266LV4M.js";
@@ -1,6 +1,6 @@
1
- import { ab as Config, al as Database, bl as NavGroup, a6 as CollectionConfig, I as ID, bE as RawDocument, aD as Field, bI as ResolvedConfig, ad as ConfigIssue } from './config-jzFGsNL6.js';
2
- export { cH as API_KEYS, cI as API_KEY_GLOBAL_OPERATIONS, cJ as API_KEY_OPERATIONS, cK as DEFAULT_MAX_VERSIONS, cL as DEFAULT_PASSWORD_EMAILS, cM as FIELD_TYPE_BASES, cN as FOLDER_LEVELS, cO as MediaFolders, cP as SSO_COOKIE, cQ as codeOfStatus, cx as hasRows, cz as isHasMany, cR as keyAllows, cD as mimeAllowedBy, cE as rowFields, cG as uniqueWithinOf } from './config-jzFGsNL6.js';
3
- export { C as CONFIG_FILE_NAMES, g as CSRF_COOKIE, h as CSRF_HEADER, D as DEFAULT_ADMIN_PATH, i as DEFAULT_API_PATH, j as DEFAULT_MAX_FILE_SIZE, k as DEFAULT_TOKEN_EXPIRATION, m as applyDefaults, n as applyPlugins, o as createRootEndpointHandler, p as fillMissing, q as findConfigFile, t as forwardedClientIp, u as generateSlugs, v as importConfig, w as mergeForUpdate, x as parseId, y as platformClientIp, z as readCookie, E as validateFields, F as writeBackupFile } from './handler-CMA1LIq7.js';
1
+ import { ab as Config, al as Database, bl as NavGroup, a6 as CollectionConfig, I as ID, bE as RawDocument, aD as Field, bI as ResolvedConfig, ad as ConfigIssue } from './config-Dgs6FE0S.js';
2
+ export { cH as API_KEYS, cI as API_KEY_GLOBAL_OPERATIONS, cJ as API_KEY_OPERATIONS, cK as DEFAULT_MAX_VERSIONS, cL as DEFAULT_PASSWORD_EMAILS, cM as FIELD_TYPE_BASES, cN as FOLDER_LEVELS, cO as MediaFolders, cP as SSO_COOKIE, cQ as codeOfStatus, cx as hasRows, cz as isHasMany, cR as keyAllows, cD as mimeAllowedBy, cE as rowFields, cG as uniqueWithinOf } from './config-Dgs6FE0S.js';
3
+ export { C as CONFIG_FILE_NAMES, g as CSRF_COOKIE, h as CSRF_HEADER, D as DEFAULT_ADMIN_PATH, i as DEFAULT_API_PATH, j as DEFAULT_MAX_FILE_SIZE, k as DEFAULT_TOKEN_EXPIRATION, m as applyDefaults, n as applyPlugins, o as createRootEndpointHandler, p as fillMissing, q as findConfigFile, t as forwardedClientIp, u as generateSlugs, v as importConfig, w as mergeForUpdate, x as parseId, y as platformClientIp, z as readCookie, E as validateFields, F as writeBackupFile } from './handler-CcQjkj5Q.js';
4
4
  export { conditionIssues } from './conditions.js';
5
5
 
6
6
  /** The session cookie the REST API sets at login. */
package/dist/internal.js CHANGED
@@ -52,7 +52,7 @@ import {
52
52
  verifyPassword,
53
53
  verifyTurnstile,
54
54
  writeBackupFile
55
- } from "./chunk-HTE5O3EG.js";
55
+ } from "./chunk-LN4M4BUP.js";
56
56
  import {
57
57
  conditionIssues
58
58
  } from "./chunk-U266LV4M.js";
@@ -1,4 +1,4 @@
1
- import { ba as Label, aD as Field, I as ID, k as AdminLocale, t as AdminSwitcher, c1 as SsoProviderRef } from './config-jzFGsNL6.js';
1
+ import { ba as Label, aD as Field, I as ID, k as AdminLocale, t as AdminSwitcher, c1 as SsoProviderRef } from './config-Dgs6FE0S.js';
2
2
  import { FieldCondition } from './conditions.js';
3
3
 
4
4
  /** A Web Component from an admin module, with its `props` (plain JSON). */
package/dist/plugin.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { a as ADMIN_ICONS, g as AdminComponent, j as AdminIcon, S as AuthUser, a3 as CliCommand, a4 as CollectionAccess, a6 as CollectionConfig, ab as Config, ac as ConfigError, ak as DashboardWidget, av as EasyCMSError, az as Endpoint, aA as EndpointRequest, aB as ErrorCode, aD as Field, aE as FieldAccess, aH as FieldError, aK as FieldTypeBase, aL as FieldTypeDefinition, aM as FieldTypeValidateContext, aY as ForbiddenError, a_ as GlobalConfig, I as ID, b8 as JobConfig, ba as Label, bl as NavGroup, bm as NotFoundError, bo as OnRequest, bp as OnRequestArgs, br as PLUGIN_API_VERSION, bw as PayloadTooLargeError, bx as Plugin, by as PluginInfo, bz as PluginTypes, bC as QueryError, bH as RequestContext, c6 as TooManyRequestsError, c7 as TypedPlugin, c8 as UnauthorizedError, cf as ValidationError, cn as Where, cu as defineFieldType, cv as definePlugin } from './config-jzFGsNL6.js';
2
- export { A as ADMIN_API_VERSION, c as AdminElementProps, k as AdminPageRoute, S as SetFieldDetail, w as warnDeprecated } from './plugin-C19Bt8ux.js';
1
+ export { a as ADMIN_ICONS, g as AdminComponent, j as AdminIcon, S as AuthUser, a3 as CliCommand, a4 as CollectionAccess, a6 as CollectionConfig, ab as Config, ac as ConfigError, ak as DashboardWidget, av as EasyCMSError, az as Endpoint, aA as EndpointRequest, aB as ErrorCode, aD as Field, aE as FieldAccess, aH as FieldError, aK as FieldTypeBase, aL as FieldTypeDefinition, aM as FieldTypeValidateContext, aY as ForbiddenError, a_ as GlobalConfig, I as ID, b8 as JobConfig, ba as Label, bl as NavGroup, bm as NotFoundError, bo as OnRequest, bp as OnRequestArgs, br as PLUGIN_API_VERSION, bw as PayloadTooLargeError, bx as Plugin, by as PluginInfo, bz as PluginTypes, bC as QueryError, bH as RequestContext, c6 as TooManyRequestsError, c7 as TypedPlugin, c8 as UnauthorizedError, cf as ValidationError, cn as Where, cu as defineFieldType, cv as definePlugin } from './config-Dgs6FE0S.js';
2
+ export { A as ADMIN_API_VERSION, c as AdminElementProps, k as AdminPageRoute, S as SetFieldDetail, w as warnDeprecated } from './plugin-8hrkYMuR.js';
3
3
  import './conditions.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easy-cms/core",
3
- "version": "0.61.0",
3
+ "version": "0.63.0",
4
4
  "description": "Embedded, code-first headless CMS for Nuxt and Next.js",
5
5
  "license": "MIT",
6
6
  "type": "module",