The kit's User implements MustVerifyEmail, so registering mails a verification link and verified holds the dashboard back until it is used. Resets go through the password broker of Guards and Providers. With MAIL_MAILER=log, both emails land in the log with their links:
rm jar; T=$(tok /register); L=storage/logs/laravel.log; G='password=Tr1cky-0wl-Barn'
curl -s $J -o /dev/null -w "$W" -d "_token=$T&name=Grace&email=grace@example.com&$G" \
-d "${G/password/password_confirmation}" $B/register
curl -s $J -o /dev/null -w "$W" $B/dashboard; grep '^Subject:' $L
V=$(grep -o 'Verify Email Address: [^ ]*' $L | cut -d' ' -f4 | tr -d '\r')
curl -s $J -o /dev/null -w "$W" "$V"
cp jar grace.jar; rm jar; T=$(tok /forgot-password)
curl -s $J -o /dev/null -w "$W" -d "_token=$T&email=ada@example.com" $B/forgot-password
R=$(grep -o 'Reset Password: [^ ]*' $L | cut -d' ' -f3 | tr -d '\r'); echo "${R:0:80}"
sqlite3 database/database.sqlite 'select email, substr(token, 1, 29) from password_reset_tokens'
K=${R#*reset-password/}; T=$(tok "/reset-password/$K"); N='password=N3w-Harbor-Owl'
curl -s $J -o /dev/null -w "$W" -d "_token=$T&token=${K%%\?*}&email=ada@example.com&$N" \
-d "${N/password/password_confirmation}" $B/reset-passwordOutput
302 http://127.0.0.1:8314/dashboard 302 http://127.0.0.1:8314/email/verify Subject: Verify your email address 302 http://127.0.0.1:8314/dashboard 302 http://127.0.0.1:8314/forgot-password http://127.0.0.1:8314/reset-password/3589eb487bddfff816548bfcd5f0f36f99317c50894 ada@example.com|$2y$12$5Eyl9DrL/xa0bauLQacaLe 302 http://127.0.0.1:8314/login
The verification link is /email/verify/{id}/{sha1 of email} with an expires time an hour ahead and a signature HMAC; with the signature altered, Grace's session got 403. The 64-character reset token is stored only as a bcrypt hash, so a leaked backup yields no working links. It expires after 60 minutes, throttle blocks a new link for 60 seconds, and a successful reset deletes the row.