{"info":{"name":"Auth Service \u2014 \ud83d\udd10 Authentication","_postman_id":"329868b1-e682-44b4-b717-4d35eb1ece8b","schema":"https:\/\/schema.getpostman.com\/json\/collection\/v2.1.0\/collection.json"},"item":[{"name":"\ud83d\udd10 Authentication","description":"Authentication endpoints: register, login, profile management, password reset, token operations, and permission checks.","item":[{"name":"Register","request":{"auth":{"type":"noauth"},"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n\t\"name\": \"John Doe\",\n\t\"email\": \"john@example.com\",\n\t\"password\": \"password123\",\n\t\"password_confirmation\": \"password123\",\n\t\"phone\": \"+966500000000\",\n\t\"roles\": [\"merchant\"]\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/auth\/register","host":["{{auth_url}}"],"path":["v1","auth","register"]},"description":"Register a new user. Roles cannot include super-admin, admin, or supervisor.\n\n**Authentication:** None required\n\n**Required fields:**\n- `name` (string) \u2014 Full name of the user\n- `email` (string) \u2014 Valid email address\n- `password` (string) \u2014 Minimum 8 characters\n- `password_confirmation` (string) \u2014 Must match password\n\n**Optional fields:**\n- `phone` (string) \u2014 Phone number with country code\n- `roles` (array of strings) \u2014 Allowed: merchant, investor, sponsor. Cannot include super-admin, admin, or supervisor."},"response":[]},{"name":"Login","event":[{"listen":"test","script":{"type":"text\/javascript","exec":["var jsonData = pm.response.json();","if (jsonData.data && jsonData.data.access_token) {","    pm.environment.set(\"auth_token\", jsonData.data.access_token);","}","if (jsonData.data && jsonData.data.user) {","    pm.environment.set(\"user_id\", jsonData.data.user.id);","}"]}}],"request":{"auth":{"type":"noauth"},"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n\t\"identifier\": \"john@example.com\",\n\t\"password\": \"password123\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/auth\/login","host":["{{auth_url}}"],"path":["v1","auth","login"]},"description":"Login with email or phone. Rate limited to 10 requests per minute.\n\n**Authentication:** None required\n\n**Required fields:**\n- `identifier` (string) \u2014 Email or phone number\n- `password` (string) \u2014 Account password\n\n**Test script:** Automatically saves `access_token` to `auth_token` and `user.id` to `user_id` environment variables."},"response":[]},{"name":"\ud83d\udcf1 OTP \u2014 Send Code","event":[],"request":{"auth":{"type":"noauth"},"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n  \"phone\": \"+966567891234\",\n  \"user_type\": \"merchant\",\n  \"channel\": \"sms\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/auth\/otp\/send","host":["{{auth_url}}"],"path":["v1","auth","otp","send"]},"description":"Send OTP verification code to phone number for login or registration.\n\n**Authentication:** None required\n\n**Required fields:**\n- `phone` (string) \u2014 Phone number (+966XXXXXXXXX or 05XXXXXXXX)\n- `user_type` (string) \u2014 Role: admin, supervisor, merchant, investor, sponsor, user\n\n**Optional:**\n- `channel` (string) \u2014 `sms` or `whatsapp` (default: sms)\n\n**Response:**\n- `is_new_user: false` \u2192 user exists, will login after verify\n- `is_new_user: true` \u2192 new user, will need to complete registration\n\n**\u26a1 Test mode:** When OTP_TEST_MODE=1, any code is accepted and no SMS is sent.\n\n**\ud83d\udccb Test Data (\u062d\u0633\u0627\u0628\u0627\u062a \u0627\u0644\u0627\u062e\u062a\u0628\u0627\u0631):**\n| Phone | user_type | Name |\n|-------|-----------|------|\n| +966567891234 | merchant | Mohammed Al-Harbi |\n| +966559876543 | merchant | Khalid Al-Otaibi |\n| +966512345678 | merchant | Noura Al-Dossary |\n| +966501234567 | investor | Ahmed Al-Rashidi |\n| +966544332211 | investor | Sultan Al-Qahtani |\n| +966538765432 | investor | Faisal Al-Ghamdi |\n| +966551112233 | sponsor | Abdulrahman Al-Fahad |\n| +966554445566 | sponsor | Majed Al-Shammari |\n| +966599999888 | investor | Test Investor |\n| +966501000001 | admin | Admin User |"},"response":[]},{"name":"\ud83d\udcf1 OTP \u2014 Verify Code","event":[{"listen":"test","script":{"type":"text\/javascript","exec":["var jsonData = pm.response.json();","","\/\/ Existing user \u2014 save auth token","if (jsonData.data && jsonData.data.token) {","    pm.environment.set('auth_token', jsonData.data.token);","    console.log('\u2705 Token saved to auth_token');","}","","\/\/ New user \u2014 save registration token","if (jsonData.data && jsonData.data.registration_token) {","    pm.environment.set('registration_token', jsonData.data.registration_token);","    console.log('\ud83d\udcdd Registration token saved \u2014 complete registration next');","}","","\/\/ Save user ID","if (jsonData.data && jsonData.data.user) {","    pm.environment.set('user_id', jsonData.data.user.id);","}","","pm.test('OTP verify returns success', function () {","    pm.response.to.have.status(200);","    pm.expect(jsonData.success).to.be.true;","});"]}}],"request":{"auth":{"type":"noauth"},"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n  \"phone\": \"+966567891234\",\n  \"code\": \"123456\",\n  \"user_type\": \"merchant\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/auth\/otp\/verify","host":["{{auth_url}}"],"path":["v1","auth","otp","verify"]},"description":"Verify OTP code and login or get registration token.\n\n**Authentication:** None required\n\n**Required fields:**\n- `phone` (string) \u2014 Same phone used in send\n- `code` (string) \u2014 OTP code received (\u26a0\ufe0f \u0627\u0644\u062d\u0642\u0644 \u0627\u0633\u0645\u0647 `code` \u0645\u0648 `otp`)\n- `user_type` (string) \u2014 Same user_type as send\n\n**\u26a1 Test mode:** Any code (e.g. 123456) works when OTP_TEST_MODE=1\n\n**Response \u2014 Existing User (\u062a\u0633\u062c\u064a\u0644 \u062f\u062e\u0648\u0644):**\n```json\n{\n  \"success\": true,\n  \"message\": \"\u062a\u0645 \u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u062f\u062e\u0648\u0644 \u0628\u0646\u062c\u0627\u062d\",\n  \"data\": {\n    \"user\": { \"id\": \"...\", \"name\": \"Mohammed Al-Harbi\", \"roles\": [\"merchant\"] },\n    \"token\": \"eyJ0eXAi...\",\n    \"token_type\": \"bearer\",\n    \"expires_in\": 3600\n  },\n  \"is_new_user\": false\n}\n```\n\n**Response \u2014 New User (\u062a\u0633\u062c\u064a\u0644 \u062c\u062f\u064a\u062f):**\n```json\n{\n  \"success\": true,\n  \"data\": {\n    \"is_new_user\": true,\n    \"registration_token\": \"xPbaVXHRV5z...\"\n  }\n}\n```\n\n**Test script:** Auto-saves `token` \u2192 `auth_token` or `registration_token`."},"response":[]},{"name":"\ud83d\udcf1 OTP \u2014 Complete Registration","event":[{"listen":"test","script":{"type":"text\/javascript","exec":["var jsonData = pm.response.json();","if (jsonData.data && jsonData.data.token) {","    pm.environment.set('auth_token', jsonData.data.token);","    console.log('\u2705 Token saved \u2014 user registered and logged in');","}","if (jsonData.data && jsonData.data.user) {","    pm.environment.set('user_id', jsonData.data.user.id);","}"]}}],"request":{"auth":{"type":"noauth"},"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n  \"registration_token\": \"{{registration_token}}\",\n  \"name\": \"\u0623\u062d\u0645\u062f \u0645\u062d\u0645\u062f\",\n  \"email\": \"ahmed@example.com\",\n  \"business_name\": \"\u0634\u0631\u0643\u0629 \u0623\u062d\u0645\u062f \u0644\u0644\u062a\u062c\u0627\u0631\u0629\",\n  \"business_type\": \"retail\",\n  \"region\": \"\u0627\u0644\u0631\u064a\u0627\u0636\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/auth\/otp\/complete-registration","host":["{{auth_url}}"],"path":["v1","auth","otp","complete-registration"]},"description":"Complete registration for new users after OTP verification.\n\n**Authentication:** None required (uses registration_token)\n\n**Required fields:**\n- `registration_token` (string) \u2014 Token from \/otp\/verify (valid for 30 minutes)\n- `name` (string) \u2014 Full name\n\n**Optional:**\n- `email` (string) \u2014 Email address\n- `business_name` (string) \u2014 Business name\n- `business_type` (string) \u2014 Business type\n- `region` (string) \u2014 Region\n\n**Response:** Returns user data + JWT token (same as login).\n\n**Note:** This endpoint is ONLY for new users who got `is_new_user: true` from \/otp\/verify."},"response":[]},{"name":"Get Current User","request":{"method":"GET","header":[],"url":{"raw":"{{auth_url}}\/v1\/auth\/me","host":["{{auth_url}}"],"path":["v1","auth","me"]},"description":"Get the currently authenticated user's profile.\n\n**Authentication:** Bearer token required"},"response":[]},{"name":"Update Profile","request":{"method":"PUT","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n\t\"name\": \"John Updated\",\n\t\"phone\": \"+966500000001\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/auth\/profile","host":["{{auth_url}}"],"path":["v1","auth","profile"]},"description":"Update the authenticated user's profile.\n\n**Authentication:** Bearer token required\n\n**Optional fields:**\n- `name` (string) \u2014 Updated full name\n- `phone` (string) \u2014 Updated phone number"},"response":[]},{"name":"Change Password","request":{"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n\t\"current_password\": \"password123\",\n\t\"password\": \"newpassword123\",\n\t\"password_confirmation\": \"newpassword123\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/auth\/change-password","host":["{{auth_url}}"],"path":["v1","auth","change-password"]},"description":"Change the authenticated user's password.\n\n**Authentication:** Bearer token required\n\n**Required fields:**\n- `current_password` (string) \u2014 Current account password\n- `password` (string) \u2014 New password, minimum 8 characters\n- `password_confirmation` (string) \u2014 Must match new password"},"response":[]},{"name":"Forgot Password","request":{"auth":{"type":"noauth"},"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n\t\"email\": \"john@example.com\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/auth\/forgot-password","host":["{{auth_url}}"],"path":["v1","auth","forgot-password"]},"description":"Send a password reset link\/code to the user's email.\n\n**Authentication:** None required\n\n**Required fields:**\n- `email` (string) \u2014 Registered email address"},"response":[]},{"name":"Reset Password","request":{"auth":{"type":"noauth"},"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n\t\"email\": \"john@example.com\",\n\t\"token\": \"reset-token-here\",\n\t\"password\": \"newpassword123\",\n\t\"password_confirmation\": \"newpassword123\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/auth\/reset-password","host":["{{auth_url}}"],"path":["v1","auth","reset-password"]},"description":"Reset a user's password using the token received via email.\n\n**Authentication:** None required\n\n**Required fields:**\n- `email` (string) \u2014 Registered email address\n- `token` (string) \u2014 Reset token from the forgot-password email\n- `password` (string) \u2014 New password, minimum 8 characters\n- `password_confirmation` (string) \u2014 Must match new password"},"response":[]},{"name":"Refresh Token","request":{"method":"POST","header":[],"url":{"raw":"{{auth_url}}\/v1\/auth\/refresh","host":["{{auth_url}}"],"path":["v1","auth","refresh"]},"description":"Refresh the current JWT access token.\n\n**Authentication:** Bearer token required (uses current token to issue a new one)"},"response":[]},{"name":"Logout","request":{"method":"POST","header":[],"url":{"raw":"{{auth_url}}\/v1\/auth\/logout","host":["{{auth_url}}"],"path":["v1","auth","logout"]},"description":"Logout and invalidate the current token.\n\n**Authentication:** Bearer token required"},"response":[]},{"name":"Send Email Verification","request":{"method":"POST","header":[],"url":{"raw":"{{auth_url}}\/v1\/auth\/email\/send-verification","host":["{{auth_url}}"],"path":["v1","auth","email","send-verification"]},"description":"Send an email verification code to the authenticated user's email address.\n\n**Authentication:** Bearer token required"},"response":[]},{"name":"Verify Email","request":{"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n\t\"code\": \"123456\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/auth\/email\/verify","host":["{{auth_url}}"],"path":["v1","auth","email","verify"]},"description":"Verify the authenticated user's email address using the code sent via email.\n\n**Authentication:** Bearer token required\n\n**Required fields:**\n- `code` (string) \u2014 Verification code received via email"},"response":[]},{"name":"\ud83d\udcde Phone \u2014 Send Verification OTP","request":{"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n  \"phone\": \"+966567891234\",\n  \"channel\": \"sms\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/auth\/phone\/send-otp","host":["{{auth_url}}"],"path":["v1","auth","phone","send-otp"]},"description":"Send OTP to verify the authenticated user's phone number.\n\n**Authentication:** Required (Bearer token)\n\n**Required fields:**\n- `phone` (string) \u2014 Phone number to verify\n\n**Optional:**\n- `channel` (string) \u2014 `sms` or `whatsapp` (default: sms)"},"response":[]},{"name":"\ud83d\udcde Phone \u2014 Verify OTP","request":{"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n  \"phone\": \"+966567891234\",\n  \"code\": \"123456\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/auth\/phone\/verify-otp","host":["{{auth_url}}"],"path":["v1","auth","phone","verify-otp"]},"description":"Verify the phone number using the OTP code.\n\n**Authentication:** Required (Bearer token)\n\n**Required fields:**\n- `phone` (string) \u2014 Same phone number\n- `code` (string) \u2014 OTP verification code"},"response":[]},{"name":"Verify Token","request":{"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n\t\"token\": \"{{auth_token}}\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/verify-token","host":["{{auth_url}}"],"path":["v1","verify-token"]},"description":"Verify if a given JWT token is valid.\n\n**Authentication:** Bearer token required\n\n**Required fields:**\n- `token` (string) \u2014 JWT token to verify"},"response":[]},{"name":"Check Permission","request":{"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n\t\"permission\": \"users.view\"\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/check-permission","host":["{{auth_url}}"],"path":["v1","check-permission"]},"description":"Check if the authenticated user has a specific permission.\n\n**Authentication:** Bearer token required\n\n**Required fields:**\n- `permission` (string) \u2014 Permission name to check (e.g. users.view)"},"response":[]},{"name":"Check Multiple Permissions","request":{"method":"POST","header":[{"key":"Content-Type","value":"application\/json"}],"body":{"mode":"raw","raw":"{\n\t\"permissions\": [\"users.view\", \"users.create\"]\n}","options":{"raw":{"language":"json"}}},"url":{"raw":"{{auth_url}}\/v1\/check-permissions","host":["{{auth_url}}"],"path":["v1","check-permissions"]},"description":"Check if the authenticated user has multiple permissions at once.\n\n**Authentication:** Bearer token required\n\n**Required fields:**\n- `permissions` (array of strings) \u2014 List of permission names to check"},"response":[]}]}],"auth":{"type":"bearer","bearer":[{"key":"token","value":"{{auth_token}}","type":"string"}]},"variable":[{"key":"auth_url","value":"http:\/\/localhost:8001","description":"Auth service base URL"},{"key":"auth_token","value":"","description":"JWT access token"},{"key":"user_id","value":"","description":"Current user ID"},{"key":"role_id","value":"","description":"Role ID for role operations"},{"key":"permission_id","value":"","description":"Permission ID for permission operations"},{"key":"service_id","value":"","description":"Service record ID for service operations"},{"key":"language","value":"ar","description":"Accept-Language header value (default: ar)"},{"key":"platform","value":"web","description":"X-Platform header value (default: web)"},{"key":"registration_token","value":""}],"event":[{"listen":"prerequest","script":{"type":"text\/javascript","exec":["pm.request.headers.add({ key: 'Accept', value: 'application\/json' });","pm.request.headers.add({ key: 'Accept-Language', value: pm.environment.get('language') || 'ar' });","pm.request.headers.add({ key: 'X-Platform', value: pm.environment.get('platform') || 'web' });"]}}]}