| 1 | # frozen_string_literal: true |
| 2 | |
| 3 | module Api |
| 4 | module V1 |
| 5 | # Token-based sign in / sign out for API clients. |
| 6 | class SessionsController < Api::BaseController |
| 7 | before_action :authenticate_token!, only: :destroy |
| 8 | |
| 9 | # POST /api/v1/auth/sign_in — returns AccountStatus. |
| 10 | # Params: email, password |
| 11 | def create |
| 12 | email = params[:email].to_s.strip.downcase |
| 13 | password = params[:password].to_s |
| 14 | |
| 15 | if email.blank? || password.blank? |
| 16 | return render_error(ERR_INVALID, "Email and password are required.", status: :unprocessable_entity) |
| 17 | end |
| 18 | |
| 19 | access_token = SmbcloudAuthService.login(email: email, password: password) |
| 20 | |
| 21 | # Keep the web account page in sync by upserting the local mirror. |
| 22 | profile = SmbcloudAuthService.me(access_token: access_token) |
| 23 | User.find_or_create_from_smbcloud(profile, access_token: access_token) |
| 24 | |
| 25 | # AccountStatus::Ready |
| 26 | render json: { Ready: { access_token: access_token } }, status: :ok |
| 27 | rescue SmbcloudAuthService::AccountNotFoundError |
| 28 | # AccountStatus::NotFound (serialised as the bare JSON string "NotFound") |
| 29 | render json: "NotFound".to_json, status: :ok |
| 30 | rescue SmbcloudAuthService::AccountIncompleteError => e |
| 31 | # AccountStatus::Incomplete { status: <account::ErrorCode u32> } |
| 32 | render json: { Incomplete: { status: incomplete_status_code(e) } }, status: :ok |
| 33 | end |
| 34 | |
| 35 | # DELETE /api/v1/auth/sign_out |
| 36 | # Header: Authorization: Bearer <access_token> |
| 37 | def destroy |
| 38 | SmbcloudAuthService.logout(access_token: @access_token) |
| 39 | head :no_content |
| 40 | end |
| 41 | |
| 42 | private |
| 43 | |
| 44 | # Map the gem's error_code to a valid account::ErrorCode (u32); default to |
| 45 | # EmailUnverified, the canonical "incomplete / verify your email" case. |
| 46 | def incomplete_status_code(error) |
| 47 | code = error.error_code.to_i |
| 48 | ACCOUNT_ERROR_CODES.include?(code) ? code : ACCOUNT_EMAIL_UNVERIFIED |
| 49 | end |
| 50 | end |
| 51 | end |
| 52 | end |