feat(auth): Microsoft OAuth sign-in/link + self-serve signup via Google/Microsoft
CI and Deploy / test (pull_request) Successful in 2m9s
CI and Deploy / deploy (pull_request) Has been skipped

Wave 7. Mirrors the existing Google ID-token-exchange pattern (Program.cs
smart-scheme dispatch, JWT bearer scheme, AuthController exchange/link/
unlink endpoints, ApplicationUser fields, reconciler columns) for
Microsoft Entra ID + personal accounts via the multi-tenant "common"
endpoint.

Google/Microsoft sign-in previously only worked for accounts already
linked to an existing local user -- there was no way to actually sign
up via OAuth. Both exchange endpoints now create a new user when no
match is found and Auth:AllowRegistration is true, same gate as
email/password registration.

Frontend: new MicrosoftAuthCard (MSAL popup flow -- Microsoft has no
vanilla-JS equivalent to Google's Identity Services script) wired into
the login page's provider tabs and the profile page's account-linking
section. REACT_APP_MICROSOFT_CLIENT_ID env var, Auth:MicrosoftClientId
config gate on the backend.
This commit is contained in:
cesnimda
2026-07-12 00:12:23 +02:00
parent fc62a659ef
commit 3081d99355
16 changed files with 729 additions and 17 deletions
+42
View File
@@ -628,6 +628,26 @@ export const translations = {
googleScriptLoadFailed: "Google auth script failed to load.",
googleUnlinked: "Google account unlinked.",
googleUnlinkFailed: "Failed to unlink Google account.",
microsoftAccountTitle: "Microsoft account",
microsoftSetupHint: "Set `REACT_APP_MICROSOFT_CLIENT_ID` in your UI environment to enable Microsoft sign-in and account linking.",
microsoftLinked: "Linked",
microsoftAvailableToLink: "Available to link",
microsoftLinkedDate: "Linked {date}",
microsoftSignInHint: "Sign in with a Microsoft account that has already been linked to your Jobbjakt user.",
continueWithMicrosoft: "Continue with Microsoft",
signInWithMicrosoft: "Sign in with Microsoft",
linkWithMicrosoft: "Link with Microsoft",
microsoftLinkedTo: "Linked to {email}.",
microsoftLinkedToYourAccount: "Linked to your Microsoft account.",
microsoftBindHint: "Bind a Microsoft account to this user so you can sign in with Microsoft and still keep your normal app roles and data.",
microsoftExchangeHint: "Exchange your Microsoft sign-in for a normal Jobbjakt session.",
microsoftSignedIn: "Signed in with Microsoft.",
microsoftLinkedSuccess: "Microsoft account linked.",
microsoftLinkedSuccessWithEmail: "Linked Microsoft account {email}.",
microsoftAuthFailed: "Microsoft authentication failed.",
microsoftUnlinked: "Microsoft account unlinked.",
microsoftUnlinkFailed: "Failed to unlink Microsoft account.",
unlinkMicrosoft: "Unlink Microsoft",
signedOut: "Signed out.",
signedInAs: "Signed in as {name}.",
unlinkGoogle: "Unlink Google",
@@ -663,6 +683,7 @@ export const translations = {
authOptional: "Authentication is optional in this environment.",
emailAndPassword: "Email & password",
google: "Google",
microsoft: "Microsoft",
createAccount: "Create account",
signedIn: "Signed in.",
rememberMe: "Remember me",
@@ -1572,6 +1593,26 @@ export const translations = {
googleScriptLoadFailed: "Kunne ikke laste Google-autentiseringsskriptet.",
googleUnlinked: "Google-konto koblet fra.",
googleUnlinkFailed: "Kunne ikke koble fra Google-kontoen.",
microsoftAccountTitle: "Microsoft-konto",
microsoftSetupHint: "Sett `REACT_APP_MICROSOFT_CLIENT_ID` i UI-miljøet ditt for å aktivere Microsoft-innlogging og kontokobling.",
microsoftLinked: "Koblet",
microsoftAvailableToLink: "Tilgjengelig for kobling",
microsoftLinkedDate: "Koblet {date}",
microsoftSignInHint: "Logg inn med en Microsoft-konto som allerede er koblet til Jobbjakt-brukeren din.",
continueWithMicrosoft: "Fortsett med Microsoft",
signInWithMicrosoft: "Logg inn med Microsoft",
linkWithMicrosoft: "Koble til med Microsoft",
microsoftLinkedTo: "Koblet til {email}.",
microsoftLinkedToYourAccount: "Koblet til Microsoft-kontoen din.",
microsoftBindHint: "Koble en Microsoft-konto til denne brukeren slik at du kan logge inn med Microsoft og fortsatt beholde vanlige approller og data.",
microsoftExchangeHint: "Bytt Microsoft-innloggingen din mot en vanlig Jobbjakt-økt.",
microsoftSignedIn: "Logget inn med Microsoft.",
microsoftLinkedSuccess: "Microsoft-konto koblet.",
microsoftLinkedSuccessWithEmail: "Koblet Microsoft-konto {email}.",
microsoftAuthFailed: "Microsoft-autentisering mislyktes.",
microsoftUnlinked: "Microsoft-konto koblet fra.",
microsoftUnlinkFailed: "Kunne ikke koble fra Microsoft-kontoen.",
unlinkMicrosoft: "Koble fra Microsoft",
signedOut: "Logget ut.",
signedInAs: "Logget inn som {name}.",
unlinkGoogle: "Koble fra Google",
@@ -1607,6 +1648,7 @@ export const translations = {
authOptional: "Autentisering er valgfri i dette miljøet.",
emailAndPassword: "E-post og passord",
google: "Google",
microsoft: "Microsoft",
createAccount: "Opprett konto",
signedIn: "Logget inn.",
rememberMe: "Husk meg",