diff --git a/package.json b/package.json index a8aaefe..9513009 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sparrow-auth", - "version": "2.31.0", + "version": "2.32.0", "scripts": { "dev": "vite dev", "build": "vite build", diff --git a/src/App.svelte b/src/App.svelte index a242847..212f6f6 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -90,9 +90,9 @@ {#if constants.APP_EDITION === AppEdition.MANAGED} - - - + + + {/if} diff --git a/src/lib/components/button/Button.svelte b/src/lib/components/button/Button.svelte index d66a22b..56dad0d 100644 --- a/src/lib/components/button/Button.svelte +++ b/src/lib/components/button/Button.svelte @@ -120,7 +120,7 @@ } .custom-btn-primary { - height: 44px; + height: 36px; font-weight: 400; background-color: white; color: black; diff --git a/src/lib/services/auth.service.ts b/src/lib/services/auth.service.ts index 144052b..80eefa0 100644 --- a/src/lib/services/auth.service.ts +++ b/src/lib/services/auth.service.ts @@ -101,40 +101,72 @@ const verifyMagicCode = async (verifyInfo: MagicCodeVerifyBody) => { return response; }; -const updateOccaisonalUpdatesStatus = async (occaisonalUpdates: OccaisonalUpdatesBody) => { - const response = await makeRequest('POST', `${apiUrl}/aoi/user/update-occasional-updates-status`, { - body: occaisonalUpdates - }) - return response; -} - -const acceptTeamInvite = async (teamId: string, inviteId: string) => { - const response = await makeRequest('POST', `${apiUrl}/api/team/${teamId}/invite/user/accept/${inviteId}`, { - body: {} - }) - return response; -} - -const resendInviteTeam = async (teamId:string, inviteId:string)=>{ - const response = await makeRequest('POST',`${apiUrl}/api/team/${teamId}/resend-invite/${inviteId}`,{}) - return response; -} - - -export { - registerUser, - loginUser, - forgotPassword, - loginWithGoogle, - verifyEmail, - resetPassword, - getUser, - sendUserEmailVerification, +const updateOccaisonalUpdatesStatus = async (occaisonalUpdates: OccaisonalUpdatesBody) => { + const response = await makeRequest( + 'POST', + `${apiUrl}/aoi/user/update-occasional-updates-status`, + { + body: occaisonalUpdates + } + ); + return response; +}; + +const acceptTeamInvite = async (teamId: string, inviteId: string) => { + const response = await makeRequest( + 'POST', + `${apiUrl}/api/team/${teamId}/invite/user/accept/${inviteId}`, + { + body: {} + } + ); + return response; +}; + +const resendInviteTeam = async (teamId: string, inviteId: string) => { + const response = await makeRequest( + 'POST', + `${apiUrl}/api/team/${teamId}/resend-invite/${inviteId}`, + {} + ); + return response; +}; + +const getConfig = async (hubUrl: string) => { + const response = await makeRequest('GET', `${hubUrl}/api/team/config`); + return response; +}; + +const getSelfHostUser = async (baseUrl: string, email: string) => { + const response = await makeRequest('GET', `${baseUrl}/api/user/email/${email}`); + + return response; +}; + +const selfHostLoginUser = async (baseUrl: string, userInfo: loginUserPostBody) => { + const response = await makeRequest('POST', `${baseUrl}/api/auth/login`, { + body: userInfo + }); + return response; +}; + +export { + registerUser, + loginUser, + forgotPassword, + loginWithGoogle, + verifyEmail, + resetPassword, + getUser, + sendUserEmailVerification, verifyUserEmail, sendMagicCodeEmail, verifyMagicCode, updateOccaisonalUpdatesStatus, acceptTeamInvite, resendInviteTeam, - registerVerifiedUser + registerVerifiedUser, + getConfig, + getSelfHostUser, + selfHostLoginUser }; diff --git a/src/pages/Auth/entry-point/EntryPoint.ViewModel.ts b/src/pages/Auth/entry-point/EntryPoint.ViewModel.ts index 673d0fa..142b521 100644 --- a/src/pages/Auth/entry-point/EntryPoint.ViewModel.ts +++ b/src/pages/Auth/entry-point/EntryPoint.ViewModel.ts @@ -1,15 +1,27 @@ -import { getUser, loginUser } from '$lib/services/auth.service'; +import { getConfig, getUser, loginUser } from '$lib/services/auth.service'; import type { loginUserPostBody } from '$lib/utils/dto'; import { checkValidation, entrySchema } from '$lib/utils/validation'; import { navigate } from 'svelte-navigator'; //---------------- Handle Login ------------------// export const handleEntry = async (entryCredentials) => { - return await getUser(entryCredentials.email); + return await getUser(entryCredentials.email); }; //------------------------- Handle Login Validation -----------------// export const handleEntryValidation = async (entryCredentials) => { - const { errorObject : response } = await checkValidation(entrySchema, entryCredentials); - return response; + const { errorObject: response } = await checkValidation(entrySchema, entryCredentials); + return response; +}; + +// Get Config deatils of backend +export const handleGetConfig = async (hubUrl: string) => { + hubUrl = hubUrl.trim(); + + //if hubUrl end with / then remove it + if (hubUrl.endsWith('/')) { + hubUrl = hubUrl.slice(0, -1); + } + const response = await getConfig(hubUrl); + return response; }; diff --git a/src/pages/Auth/entry-point/EntryPoint.svelte b/src/pages/Auth/entry-point/EntryPoint.svelte index 14bbec2..5585add 100644 --- a/src/pages/Auth/entry-point/EntryPoint.svelte +++ b/src/pages/Auth/entry-point/EntryPoint.svelte @@ -1,5 +1,5 @@ + +{#if isLogin} + +{:else} + +
+
+ +
+

Sparrow

+
+ +
+

+ Welcome Back! +

+

+ Let’s get back to work +

+
+ +
+

+ Gain full control of your deployment with our self-hosting feature. +

+
+ +
+ +
+
+{/if} + + diff --git a/src/pages/Auth/self-host-login-page/self-host-login-page.ts b/src/pages/Auth/self-host-login-page/self-host-login-page.ts new file mode 100644 index 0000000..beb1ed5 --- /dev/null +++ b/src/pages/Auth/self-host-login-page/self-host-login-page.ts @@ -0,0 +1,28 @@ +import { loginUser, selfHostLoginUser } from '$lib/services/auth.service'; +import type { loginUserPostBody } from '$lib/utils/dto'; +import { checkValidation, loginSchema } from '$lib/utils/validation'; +import { navigate } from 'svelte-navigator'; + +//------------------------------Navigation-------------------------------// +export const navigateToRegister = () => { + navigate('/register'); +}; + +//---------------- Handle Login ------------------// +export const handleLogin = async (loginCredentials: loginUserPostBody) => { + const baseUrl = sessionStorage.getItem('selfhost-backendurl') || ''; + if (!baseUrl) { + return { isSuccessful: false, message: 'Self Host URL not found. Please try again.' }; + } + return await selfHostLoginUser(baseUrl, loginCredentials); +}; + +//------------------------- Handle Login Validation -----------------// +export const handleLoginValidation = async (loginCredentials: loginUserPostBody) => { + const { isError, errorObject } = await checkValidation(loginSchema, loginCredentials); + if (isError) { + return errorObject; + } + + return; +}; diff --git a/src/pages/Auth/self-host-password-login/SelfHostPasswordLogin.ViewModel.ts b/src/pages/Auth/self-host-password-login/SelfHostPasswordLogin.ViewModel.ts new file mode 100644 index 0000000..fedd667 --- /dev/null +++ b/src/pages/Auth/self-host-password-login/SelfHostPasswordLogin.ViewModel.ts @@ -0,0 +1,17 @@ +import { getSelfHostUser, getUser } from '$lib/services/auth.service'; +import { checkValidation, entrySchema } from '$lib/utils/validation'; + +//---------------- Handle Login ------------------// +export const handleEntry = async (entryCredentials) => { + const baseUrl = sessionStorage.getItem('selfhost-backendurl') || ''; + if (!baseUrl) { + return { isSuccessful: false, message: 'Self Host URL not found. Please try again.' }; + } + return await getSelfHostUser(baseUrl, entryCredentials.email); +}; + +//------------------------- Handle Login Validation -----------------// +export const handleEntryValidation = async (entryCredentials) => { + const { errorObject: response } = await checkValidation(entrySchema, entryCredentials); + return response; +}; diff --git a/src/pages/Auth/self-host-password-login/SelfHostPasswordLogin.svelte b/src/pages/Auth/self-host-password-login/SelfHostPasswordLogin.svelte new file mode 100644 index 0000000..b89a15a --- /dev/null +++ b/src/pages/Auth/self-host-password-login/SelfHostPasswordLogin.svelte @@ -0,0 +1,277 @@ + + + +
+
+ +
+

Sparrow

+
+ +
+

+ Welcome to Sparrow +

+

+ Let’s get back to work +

+
+ + + + + + + +
+

+ Gain full control of your deployment with our self-hosting feature. +

+
+
+ +
+
+ + diff --git a/src/pages/Auth/team-invite-acceptance/TeamInviteAcceptance.svelte b/src/pages/Auth/team-invite-acceptance/TeamInviteAcceptance.svelte index bd40f1e..e18948f 100644 --- a/src/pages/Auth/team-invite-acceptance/TeamInviteAcceptance.svelte +++ b/src/pages/Auth/team-invite-acceptance/TeamInviteAcceptance.svelte @@ -30,7 +30,7 @@ const sparrowRedirect = `sparrow://`; - // sparrow://?accessToken=${accessToken}&refreshToken=${refreshToken}&response=${JSON.stringify(response)}&event=login&method=email`; + // sparrow://?selfhostBackendUrl=${constants.APP_EDITION === AppEdition.SELFHOSTED ? constants.API_URL : ""}&selfhostAdminUrl=${constants.APP_EDITION === AppEdition.SELFHOSTED ? constants.SPARROW_ADMIN_URL : ""}&selfhostWebUrl=${constants.APP_EDITION === AppEdition.SELFHOSTED ? constants.SPARROW_WEB_URL : ""}&accessToken=${accessToken}&refreshToken=${refreshToken}&response=${JSON.stringify(response)}&event=login&method=email`; const buttonClick = () => { navigate(sparrowRedirect); diff --git a/src/pages/Auth/update-password/UpdatePassword.svelte b/src/pages/Auth/update-password/UpdatePassword.svelte index 474d958..8bbd386 100644 --- a/src/pages/Auth/update-password/UpdatePassword.svelte +++ b/src/pages/Auth/update-password/UpdatePassword.svelte @@ -16,6 +16,7 @@ import CircleCheck from '$lib/assets/CircleCheck.svelte'; import AiSparkle from '$lib/assets/AiSparkle.svelte'; + import { AppEdition } from '$lib/utils/enums/enums'; export let id: string; let seconds = 300; // Changed from 600 to 300 (5 minutes) @@ -585,7 +586,7 @@ isRegistered = true; const accessToken = response?.data.accessToken?.token; const refreshToken = response?.data.refreshToken?.token; - const sparrowRedirect = `sparrow://?accessToken=${accessToken}&refreshToken=${refreshToken}&response=${JSON.stringify(response.data)}&event=register&method=email`; + const sparrowRedirect = `sparrow://?selfhostBackendUrl=${constants.APP_EDITION === AppEdition.SELFHOSTED ? constants.API_URL : ""}&selfhostAdminUrl=${constants.APP_EDITION === AppEdition.SELFHOSTED ? constants.SPARROW_ADMIN_URL : ""}&selfhostWebUrl=${constants.APP_EDITION === AppEdition.SELFHOSTED ? constants.SPARROW_WEB_URL : ""}&accessToken=${accessToken}&refreshToken=${refreshToken}&response=${JSON.stringify(response.data)}&event=register&method=email`; const sparrowWebRedirect = constants.SPARROW_WEB_URL + `?accessToken=${accessToken}&refreshToken=${refreshToken}&response=${JSON.stringify(response)}&event=register&method=email`; diff --git a/src/pages/Auth/verify-email/VerifyEmail.svelte b/src/pages/Auth/verify-email/VerifyEmail.svelte index 464f7cd..4aed161 100644 --- a/src/pages/Auth/verify-email/VerifyEmail.svelte +++ b/src/pages/Auth/verify-email/VerifyEmail.svelte @@ -609,7 +609,7 @@ ); } - // const sparrowRedirect = `sparrow://?accessToken=${accessToken}&refreshToken=${refreshToken}&response=${JSON.stringify(response.data)}&event=register&method=email`; + // const sparrowRedirect = `sparrow://?selfhostBackendUrl=${constants.APP_EDITION === AppEdition.SELFHOSTED ? constants.API_URL : ""}&selfhostAdminUrl=${constants.APP_EDITION === AppEdition.SELFHOSTED ? constants.SPARROW_ADMIN_URL : ""}&selfhostWebUrl=${constants.APP_EDITION === AppEdition.SELFHOSTED ? constants.SPARROW_WEB_URL : ""}&accessToken=${accessToken}&refreshToken=${refreshToken}&response=${JSON.stringify(response.data)}&event=register&method=email`; // const sparrowWebRedirect = // constants.SPARROW_WEB_URL + // `?accessToken=${accessToken}&refreshToken=${refreshToken}&response=${JSON.stringify(response)}&event=register&method=email`; diff --git a/src/pages/Auth/verify-magic-code/VerifyMagicCode.svelte b/src/pages/Auth/verify-magic-code/VerifyMagicCode.svelte index 36a2301..a912169 100644 --- a/src/pages/Auth/verify-magic-code/VerifyMagicCode.svelte +++ b/src/pages/Auth/verify-magic-code/VerifyMagicCode.svelte @@ -15,6 +15,7 @@ import CircleCheck from '$lib/assets/CircleCheck.svelte'; import { handleVerifyUserEmail, isSuccessfulResponseMagicCode } from './verify-magic-code'; + import { AppEdition } from '$lib/utils/enums/enums'; export let id: string; export let name: string = ''; @@ -596,7 +597,7 @@ isRegistered = true; const accessToken = response?.data.accessToken?.token; const refreshToken = response?.data.refreshToken?.token; - const sparrowRedirect = `sparrow://?accessToken=${accessToken}&refreshToken=${refreshToken}&response=${JSON.stringify(response.data)}&event=login&method=code`; + const sparrowRedirect = `sparrow://?selfhostBackendUrl=${constants.APP_EDITION === AppEdition.SELFHOSTED ? constants.API_URL : ""}&selfhostAdminUrl=${constants.APP_EDITION === AppEdition.SELFHOSTED ? constants.SPARROW_ADMIN_URL : ""}&selfhostWebUrl=${constants.APP_EDITION === AppEdition.SELFHOSTED ? constants.SPARROW_WEB_URL : ""}&accessToken=${accessToken}&refreshToken=${refreshToken}&response=${JSON.stringify(response.data)}&event=login&method=code`; const sparrowWebRedirect = constants.SPARROW_WEB_URL + `?accessToken=${accessToken}&refreshToken=${refreshToken}&response=${JSON.stringify(response)}&event=login&method=code`;