🔑 Password Reset Explorer
Complete password recovery system testing. Help users regain access to their accounts securely.
🚀 Initiate Password Reset
Send a password reset email to the user:
https://api.swapbits.co/auth/forgot-passwordRequest password reset email
Parámetros
Email address of the account to reset
Comando cURL
curl -X POST 'https://api.swapbits.co/auth/forgot-password' \
-H 'Content-Type: application/json'🔐 Reset Password with Code
Complete the password reset using the code from email:
https://api.swapbits.co/auth/reset-passwordReset password using verification code
Parámetros
Email address of the account
6-digit code from reset email
New password (8+ chars, secure)
Comando cURL
curl -X POST 'https://api.swapbits.co/auth/reset-password' \
-H 'Content-Type: application/json'🔄 Change Password (Authenticated)
Change password when user knows current password:
https://api.swapbits.co/auth/change-passwordChange password (requires authentication)
Autenticación
Parámetros
User's current password
New password to set
Comando cURL
curl -X POST 'https://api.swapbits.co/auth/change-password' \
-H 'Content-Type: application/json'Response Scenarios
Password Reset Request
✅ Reset Email Sent (Code 1000)
Reset email dispatched - Check inbox for reset code.
{
"code": 1000,
"message": "Password reset email sent",
"data": {
"email": "user@example.com",
"codeSent": true,
"expiresIn": 300,
"rateLimit": {
"remaining": 2,
"resetTime": "2024-01-15T11:00:00Z"
}
}
}
Important: Code expires in 5 minutes (300 seconds)
❌ Account Not Found (Code 4004)
Email not registered - No account found with this email.
{
"code": 4004,
"message": "Account not found",
"id": "error-trace-id"
}
Action: Check email spelling or register a new account
⚠️ Rate Limited (Code 4029)
Too many requests - Reset requests temporarily blocked.
{
"code": 4029,
"message": "Too many reset requests",
"data": {
"retryAfter": 180,
"maxAttempts": 3,
"windowMinutes": 15
},
"id": "error-trace-id"
}
Action: Wait 3 minutes before trying again
Password Reset Completion
✅ Password Reset Successful (Code 1006)
Password updated successfully - User can now login with new password.
{
"code": 1006,
"message": "Password reset successfully",
"data": {
"passwordChanged": true,
"sessionRevoked": true,
"loginRequired": true
}
}
Next step: Use Login Explorer with new password
❌ Invalid Reset Code (Code 4005)
Code verification failed - Code is incorrect, expired, or already used.
{
"code": 4005,
"message": "Invalid or expired reset code",
"data": {
"codeExpired": true,
"attemptsRemaining": 2
},
"id": "error-trace-id"
}
Action: Request a new reset code if expired, or check code accuracy
Password Change (Authenticated)
✅ Password Changed (Code 1006)
Password updated - Successfully changed while authenticated.
{
"code": 1006,
"message": "Password changed successfully",
"data": {
"passwordChanged": true,
"sessionMaintained": true,
"securityNotification": true
}
}
Note: Current session remains active, security email sent
❌ Current Password Incorrect (Code 4001)
Authentication failed - Current password is wrong.
{
"code": 4001,
"message": "Current password is incorrect",
"data": {
"attemptsRemaining": 4,
"lockoutWarning": false
},
"id": "error-trace-id"
}
Action: Verify current password or use forgot password flow
🔄 Complete Password Recovery Flow
Step-by-step Password Recovery
Forgot Password Flow:
- Request Reset → POST
/auth/forgot-passwordwith email address - Check Email → Look for reset code in inbox (check spam folder)
- Note Expiration → Code expires in 5 minutes from receipt
- Reset Password → POST
/auth/reset-passwordwith email, code, and new password - Login Again → All sessions revoked, login required with new password
Change Password Flow (When Authenticated):
- Authenticate → Ensure you have valid access token
- Verify Current → Know your current password for verification
- Change Password → POST
/auth/change-passwordwith old and new passwords - Continue Session → Current session remains active
Security Features:
- Reset codes expire in 5 minutes
- Maximum 3 reset requests per 15-minute window
- All user sessions revoked after password reset
- Security notification emails sent for changes
- Failed attempts are tracked and limited
💻 Integration Examples
JavaScript/TypeScript
interface PasswordResetManager {
requestReset(email: string): Promise<boolean>;
resetPassword(email: string, code: string, newPassword: string): Promise<boolean>;
changePassword(currentPassword: string, newPassword: string): Promise<boolean>;
}
class SwapBitsPassword implements PasswordResetManager {
private baseUrl = 'https://api.swapbits.co';
private accessToken?: string;
constructor(accessToken?: string) {
this.accessToken = accessToken;
}
async requestReset(email: string): Promise<boolean> {
const response = await fetch(`${this.baseUrl}/auth/forgot-password`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ email }),
});
const result = await response.json();
if (result.code === 1000) {
console.log(`Reset email sent to ${email}`);
console.log(`Code expires in ${result.data.expiresIn} seconds`);
console.log(`Remaining attempts: ${result.data.rateLimit.remaining}`);
return true;
} else if (result.code === 4029) {
throw new Error(`Rate limited. Retry after ${result.data.retryAfter} seconds`);
} else {
throw new Error(`Reset request failed: ${result.message} (Code: ${result.code})`);
}
}
async resetPassword(email: string, code: string, newPassword: string): Promise<boolean> {
// Validate password strength first
const validation = this.validatePassword(newPassword);
if (!validation.valid) {
throw new Error(`Password validation failed: ${validation.errors.join(', ')}`);
}
const response = await fetch(`${this.baseUrl}/auth/reset-password`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
code,
newPassword,
}),
});
const result = await response.json();
if (result.code === 1006) {
console.log('Password reset successful');
console.log('All sessions have been revoked - please login again');
return true;
} else if (result.code === 4005) {
throw new Error(`Reset code invalid or expired. Attempts remaining: ${result.data.attemptsRemaining}`);
} else {
throw new Error(`Password reset failed: ${result.message} (Code: ${result.code})`);
}
}
async changePassword(currentPassword: string, newPassword: string): Promise<boolean> {
if (!this.accessToken) {
throw new Error('Authentication required for password change');
}
// Validate new password
const validation = this.validatePassword(newPassword);
if (!validation.valid) {
throw new Error(`Password validation failed: ${validation.errors.join(', ')}`);
}
const response = await fetch(`${this.baseUrl}/auth/change-password`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
currentPassword,
newPassword,
}),
});
const result = await response.json();
if (result.code === 1006) {
console.log('Password changed successfully');
console.log('Security notification email sent');
return true;
} else if (result.code === 4001) {
throw new Error(`Current password incorrect. Attempts remaining: ${result.data.attemptsRemaining}`);
} else {
throw new Error(`Password change failed: ${result.message} (Code: ${result.code})`);
}
}
private validatePassword(password: string): { valid: boolean; errors: string[] } {
const errors: string[] = [];
if (password.length < 8) {
errors.push('Password must be at least 8 characters long');
}
if (!/[A-Z]/.test(password)) {
errors.push('Password must contain at least one uppercase letter');
}
if (!/[a-z]/.test(password)) {
errors.push('Password must contain at least one lowercase letter');
}
if (!/[0-9]/.test(password)) {
errors.push('Password must contain at least one number');
}
if (!/[!@#$%^&*(),.?":{}|<>]/.test(password)) {
errors.push('Password must contain at least one symbol');
}
return {
valid: errors.length === 0,
errors,
};
}
}
// Usage examples
const passwordManager = new SwapBitsPassword();
// Request password reset
try {
await passwordManager.requestReset('user@example.com');
console.log('Check your email for reset code');
} catch (error) {
console.error('Reset request failed:', error.message);
}
// Complete password reset
try {
const resetCode = prompt('Enter reset code from email:');
const newPassword = prompt('Enter new password:');
await passwordManager.resetPassword('user@example.com', resetCode, newPassword);
console.log('Password reset complete! Please login again.');
} catch (error) {
console.error('Password reset failed:', error.message);
}
// Change password (when authenticated)
const authenticatedManager = new SwapBitsPassword('your-access-token');
try {
const currentPass = prompt('Enter current password:');
const newPass = prompt('Enter new password:');
await authenticatedManager.changePassword(currentPass, newPass);
console.log('Password changed successfully!');
} catch (error) {
console.error('Password change failed:', error.message);
}
Python
import requests
import re
import time
from typing import Dict, Any, List
class SwapBitsPassword:
def __init__(self, access_token: str = None):
self.base_url = 'https://api.swapbits.co'
self.access_token = access_token
def request_reset(self, email: str) -> bool:
"""Request password reset email"""
response = requests.post(
f'{self.base_url}/auth/forgot-password',
json={'email': email}
)
result = response.json()
if result['code'] == 1000:
print(f"Reset email sent to {email}")
print(f"Code expires in {result['data']['expiresIn']} seconds")
print(f"Remaining attempts: {result['data']['rateLimit']['remaining']}")
return True
elif result['code'] == 4029:
retry_after = result['data']['retryAfter']
raise Exception(f"Rate limited. Retry after {retry_after} seconds")
else:
raise Exception(f"Reset request failed: {result['message']} (Code: {result['code']})")
def reset_password(self, email: str, code: str, new_password: str) -> bool:
"""Complete password reset with verification code"""
# Validate password first
validation = self.validate_password(new_password)
if not validation['valid']:
raise ValueError(f"Password validation failed: {', '.join(validation['errors'])}")
response = requests.post(
f'{self.base_url}/auth/reset-password',
json={
'email': email,
'code': code,
'newPassword': new_password
}
)
result = response.json()
if result['code'] == 1006:
print("Password reset successful")
print("All sessions have been revoked - please login again")
return True
elif result['code'] == 4005:
attempts = result['data'].get('attemptsRemaining', 0)
raise Exception(f"Reset code invalid or expired. Attempts remaining: {attempts}")
else:
raise Exception(f"Password reset failed: {result['message']} (Code: {result['code']})")
def change_password(self, current_password: str, new_password: str) -> bool:
"""Change password when authenticated"""
if not self.access_token:
raise Exception('Authentication required for password change')
# Validate new password
validation = self.validate_password(new_password)
if not validation['valid']:
raise ValueError(f"Password validation failed: {', '.join(validation['errors'])}")
response = requests.post(
f'{self.base_url}/auth/change-password',
headers={'Authorization': f'Bearer {self.access_token}'},
json={
'currentPassword': current_password,
'newPassword': new_password
}
)
result = response.json()
if result['code'] == 1006:
print("Password changed successfully")
print("Security notification email sent")
return True
elif result['code'] == 4001:
attempts = result['data'].get('attemptsRemaining', 0)
raise Exception(f"Current password incorrect. Attempts remaining: {attempts}")
else:
raise Exception(f"Password change failed: {result['message']} (Code: {result['code']})")
def validate_password(self, password: str) -> Dict[str, Any]:
"""Validate password against security requirements"""
errors = []
if len(password) < 8:
errors.append('Password must be at least 8 characters long')
if not re.search(r'[A-Z]', password):
errors.append('Password must contain at least one uppercase letter')
if not re.search(r'[a-z]', password):
errors.append('Password must contain at least one lowercase letter')
if not re.search(r'[0-9]', password):
errors.append('Password must contain at least one number')
if not re.search(r'[!@#$%^&*(),.?":{}|<>]', password):
errors.append('Password must contain at least one symbol')
return {
'valid': len(errors) == 0,
'errors': errors
}
def complete_reset_flow(self, email: str) -> bool:
"""Complete reset flow with user interaction"""
try:
# Request reset
self.request_reset(email)
# Get code from user
code = input("Enter the 6-digit code from your email: ")
# Get new password
while True:
new_password = input("Enter your new password: ")
validation = self.validate_password(new_password)
if validation['valid']:
break
else:
print("Password requirements not met:")
for error in validation['errors']:
print(f" - {error}")
print()
# Complete reset
self.reset_password(email, code, new_password)
return True
except Exception as e:
print(f"Reset flow failed: {e}")
return False
# Usage examples
password_manager = SwapBitsPassword()
# Forgot password flow
try:
email = 'user@example.com'
password_manager.request_reset(email)
print("Check your email for reset code")
# Wait for user to get code, then complete reset
code = input("Enter reset code: ")
new_password = input("Enter new password: ")
password_manager.reset_password(email, code, new_password)
print("Password reset complete! Please login again.")
except Exception as e:
print(f"Password reset failed: {e}")
# Change password (when authenticated)
authenticated_manager = SwapBitsPassword('your-access-token')
try:
current_password = input("Enter current password: ")
new_password = input("Enter new password: ")
authenticated_manager.change_password(current_password, new_password)
print("Password changed successfully!")
except Exception as e:
print(f"Password change failed: {e}")
# Complete interactive reset flow
password_manager.complete_reset_flow('user@example.com')
🔗 Related Explorers
- 🔑 Login Explorer - Access account after password reset
- 📧 Email Verification Explorer - Email verification flows
- 👤 Profile Explorer - Account management after login
- 🛡️ 2FA Explorer - Additional security after password change
🆘 Troubleshooting
🔧 Common Password Issues & Solutions
Problem: No reset email received Solution: Check spam folder, verify email spelling, ensure account exists
Problem: Reset code expired Solution: Request new reset code (codes expire in 5 minutes)
Problem: "Too many reset requests" Solution: Wait 15 minutes between attempts (3 max per window)
Problem: Current password rejected during change Solution: Verify current password or use forgot password flow
Problem: New password rejected Solution: Ensure 8+ chars with uppercase, lowercase, numbers, and symbols
Problem: Reset code not working Solution: Check for typos, ensure code wasn't already used, request new one if expired