@fabriq/auth-client
Advanced tools
Comparing version 0.0.6 to 0.0.7
@@ -9,3 +9,2 @@ import { decodeAuthenticationTokens } from "./token.js"; | ||
const baseUri = uriParams.baseUri; | ||
const schema = uriParams.schema; | ||
async function getLoggedInUser() { | ||
@@ -43,3 +42,3 @@ const authenticationTokens = await authenticationTokensRepository | ||
state: "notAuthenticated", | ||
loginUrl: `${schema}://${baseUri}/${organizationId}/${loginPath}`, | ||
loginUrl: `${baseUri}/${organizationId}/${loginPath}`, | ||
}; | ||
@@ -55,2 +54,3 @@ }, | ||
const result = await server.requestAuthorization({ | ||
type: "public", | ||
organizationId, | ||
@@ -60,3 +60,3 @@ codeChallenge: codePair.codeChallenge, | ||
scope: ["openid"], | ||
redirectUri: redirectUrl ?? `${schema}://${baseUri}`, | ||
redirectUri: redirectUrl ?? baseUri, | ||
codeChallengeMethod: "S256", | ||
@@ -85,3 +85,2 @@ clientId, | ||
} | ||
//TODO: Check in server if this user has SAML and redirect towards idp for authentication | ||
return await fabriqIdentityProvider.authenticate(id, organizationId, authId, credentials); | ||
@@ -106,2 +105,3 @@ }, | ||
const tokensResult = await server.issueTokensFromAuthorizationCode({ | ||
type: "public", | ||
clientId: id, | ||
@@ -112,3 +112,3 @@ code: authorizationCode, | ||
scope: ["openid"], | ||
redirectUri: redirectUri ?? `${schema}://${baseUri}`, | ||
redirectUri: redirectUri ?? baseUri, | ||
}); | ||
@@ -128,4 +128,3 @@ if (tokensResult.outcome === "notIssued") { | ||
outcome: "authenticationFinalized", | ||
redirectUrl: redirectUri ?? | ||
`${schema}://${baseUri}`, | ||
redirectUrl: redirectUri ?? baseUri, | ||
authenticationTokens, | ||
@@ -135,3 +134,3 @@ }; | ||
getLoggedInUser, | ||
async requestUserRegistration(organizationId, credentials) { | ||
async requestUserRegistration(organizationId, credentials, information) { | ||
const user = await getLoggedInUser(); | ||
@@ -141,3 +140,3 @@ if (user) { | ||
} | ||
return await server.registerUser(clientId, organizationId, credentials); | ||
return await server.registerUser(clientId, organizationId, credentials, information.firstName, information.lastName, information.language); | ||
}, | ||
@@ -308,3 +307,3 @@ async confirmRegistration(confirmationToken) { | ||
}, | ||
async confirmInvitedUser(password, firstName, lastName, invitationToken, backendSecret) { | ||
async confirmInvitedUser(password, firstName, lastName, invitationToken, language, backendSecret) { | ||
const user = await getLoggedInUser(); | ||
@@ -320,2 +319,3 @@ if (user) { | ||
invitationToken: invitationToken, | ||
language, | ||
}); | ||
@@ -328,3 +328,10 @@ }, | ||
} | ||
const userAuthResult = await server.checkUserIdp({ clientId: id, organizationId, emailAddress, authId, redirectUri }); | ||
const userAuthResult = await server.checkUserIdp({ | ||
type: "public", | ||
clientId: id, | ||
organizationId, | ||
emailAddress, | ||
authId, | ||
redirectUri, | ||
}); | ||
if (userAuthResult.outcome === "failed") { | ||
@@ -331,0 +338,0 @@ return { outcome: "notProvided", reason: userAuthResult.reason }; |
@@ -11,3 +11,3 @@ import * as z from "../../deps/deno_land/x/zod_v3.11.6/mod.js"; | ||
export async function createJwt(payload, key) { | ||
const header = { alg: "EdDSA", typ: "JWT" }; | ||
const header = { typ: "JWT", alg: "EdDSA" }; | ||
const headerStr = base64Url.encode(encoder.encode(JSON.stringify(header))); | ||
@@ -14,0 +14,0 @@ const payloadStr = base64Url.encode(encoder.encode(JSON.stringify(payload))); |
@@ -6,3 +6,3 @@ { | ||
"name": "@fabriq/auth-client", | ||
"version": "0.0.6", | ||
"version": "0.0.7", | ||
"description": "This is the fabriq auth client package, that interacts with the future auth service.", | ||
@@ -9,0 +9,0 @@ "license": "MIT", |
@@ -19,3 +19,2 @@ import { Server } from "../../server/interface/_mod.js"; | ||
baseUri: string; | ||
schema: "http" | "https"; | ||
paths: { | ||
@@ -22,0 +21,0 @@ login: string; |
@@ -16,3 +16,3 @@ import type { AuthorizationTokens, Credentials } from "../../server/interface/_mod.js"; | ||
outcome: "authenticationFailed"; | ||
reason: "userWithNoPassword" | "wrongPassword" | "alreadyLoggedIn" | "userDoesNotExist"; | ||
reason: "userWithNoPassword" | "wrongPassword" | "alreadyLoggedIn" | "userDoesNotExist" | "tooManyAttempts"; | ||
}; | ||
@@ -23,3 +23,2 @@ export interface Client { | ||
baseUri: string; | ||
schema: "http" | "https"; | ||
paths: { | ||
@@ -60,3 +59,7 @@ login: string; | ||
*/ | ||
requestUserRegistration(organizationId: string, credentials: Credentials): Promise<RequestUserRegistrationResult>; | ||
requestUserRegistration(organizationId: string, credentials: Credentials, information: { | ||
firstName: string; | ||
lastName: string; | ||
language: string; | ||
}): Promise<RequestUserRegistrationResult>; | ||
/** | ||
@@ -89,3 +92,3 @@ * Confirms to the server the registration of the user to which the provided | ||
inviteUser(organizationId: string, emailAddress: string): Promise<InviteResult>; | ||
confirmInvitedUser(password: string, firstName: string, lastName: string, invitationToken: string, backendSecret?: string): Promise<CreateInvitedUserResult>; | ||
confirmInvitedUser(password: string, firstName: string, lastName: string, invitationToken: string, language: string, backendSecret?: string): Promise<CreateInvitedUserResult>; | ||
getUserAuthenticationUri(input: { | ||
@@ -125,3 +128,3 @@ organizationId: string; | ||
outcome: "authenticationFailed"; | ||
reason?: "clientDoesNotExist" | "alreadyLoggedIn" | "notRegistered" | "authCodeNotGranted" | "authProcessNotStarted" | "authProcessEnded" | "codeChallengeMismatch"; | ||
reason?: "clientDoesNotExist" | "alreadyLoggedIn" | "notRegistered" | "authCodeNotGranted" | "authProcessNotStarted" | "authProcessEnded" | "codeChallengeMismatch" | "clientCredentialsNotValid"; | ||
}; | ||
@@ -132,3 +135,3 @@ export declare type RequestUserRegistrationResult = { | ||
outcome: "notRegistered"; | ||
reason: "clientDoesNotExist" | "emailAlreadyUsed" | "alreadyLoggedIn" | "userInformationNotValid" | "emailNotValid" | "passwordNotCompliant"; | ||
reason: "clientDoesNotExist" | "emailAlreadyUsed" | "alreadyLoggedIn" | "userInformationNotValid" | "emailNotValid" | "passwordNotCompliant" | "clientTypeNotValid"; | ||
}; | ||
@@ -170,3 +173,3 @@ export interface CodePair { | ||
outcome: "rejected"; | ||
reason: "userNotActive" | "userDoesNotExist" | "userLoggedIn" | "clientDoesNotExist" | "userIdpNotInternal"; | ||
reason: "userNotActive" | "userDoesNotExist" | "userLoggedIn" | "clientDoesNotExist" | "userIdpNotInternal" | "clientTypeNotValid"; | ||
}; | ||
@@ -207,3 +210,3 @@ export declare type RequestChangePasswordAfterResetResult = { | ||
outcome: "rejected"; | ||
reason?: "invalidToken" | "expiredToken" | "passwordNotCompliant" | "userInformationNotValid" | "userAlreadyConfirmed" | "userNotInvited" | "userLoggedIn" | "djangoBackendError" | "passwordNotSet" | "userNotSaved"; | ||
reason?: "invalidToken" | "expiredToken" | "passwordNotCompliant" | "userInformationNotValid" | "userAlreadyConfirmed" | "userNotInvited" | "userLoggedIn" | "djangoBackendError" | "passwordNotSet" | "userNotSaved" | "personalInformationNotSaved"; | ||
}; | ||
@@ -221,3 +224,3 @@ export declare type UserTokenPayload = { | ||
outcome: "notProvided"; | ||
reason: "userLoggedIn" | "emailDoesNotExist" | "clientDoesNotExist" | "authIdNotValid" | "userNotActive" | "idpNameNotValid" | "samlRequestError" | "idpInformationError"; | ||
reason: "userLoggedIn" | "emailDoesNotExist" | "clientDoesNotExist" | "authIdNotValid" | "userNotActive" | "idpNameNotValid" | "samlRequestError" | "idpInformationError" | "clientCredentialsAreNotValid"; | ||
}; | ||
@@ -224,0 +227,0 @@ declare type InvitedUserAuthenticationUriResult = { |
import { JsonWebPublicKey } from "../../libs/jwt/_mod_full.js"; | ||
import { ClientPaths, Scope, User } from "../lib/types.js"; | ||
import { Scope, User } from "../lib/types.js"; | ||
export interface Server { | ||
@@ -8,3 +8,3 @@ registerOrganization(name: string, apiKey: string): Promise<RegisterOrganizationResult>; | ||
*/ | ||
registerSharedClient(baseUri: string, paths: ClientPaths, schema: "http" | "https", apiKey: string): Promise<RegisterSharedClientResult>; | ||
registerSharedClient(input: RegisterSharedClientInput): Promise<RegisterSharedClientResult>; | ||
saveExternalIdp(input: { | ||
@@ -19,3 +19,10 @@ organizationId: string; | ||
}): Promise<RegisterExternalIdpResult>; | ||
registerUser(clientId: string, organizationId: string, credentials: Credentials): Promise<RegisterUserResult>; | ||
saveAuthConfig(organizationId: string, apiKey: string, input: { | ||
ssoMandatory: true; | ||
defaultSSOId: string; | ||
} | { | ||
ssoMandatory: false; | ||
defaultSSOId?: string; | ||
}): Promise<SaveAuthConfigResult>; | ||
registerUser(clientId: string, organizationId: string, credentials: Credentials, firstName: string, lastName: string, language: string): Promise<RegisterUserResult>; | ||
/** | ||
@@ -35,3 +42,3 @@ * Confirms email address of the user from a previously generated confirmation | ||
*/ | ||
requestAuthCode(organizationId: string, idpToken: string): Promise<RequestAuthCodeResult>; | ||
requestAuthCode(organizationId: string, idpToken: string, clientSecret?: string): Promise<RequestAuthCodeResult>; | ||
requestAuthCodeAfterSAML(samlResponse: string, relayState: string): Promise<RequestAuthCodeAfterSAMLResult>; | ||
@@ -63,3 +70,5 @@ /** | ||
checkUserIdp(input: { | ||
type: "public" | "confidential"; | ||
clientId: string; | ||
clientSecret?: string; | ||
organizationId: string; | ||
@@ -78,2 +87,17 @@ emailAddress: string; | ||
}): Promise<CheckInvitedUserIdpResult>; | ||
renameUser(input: { | ||
organizationId: string; | ||
userId: string; | ||
apiKey: string; | ||
changes: { | ||
firstName?: string; | ||
lastName?: string; | ||
}; | ||
}): Promise<RenameUserOutcome>; | ||
changeUserPreferences(input: { | ||
organizationId: string; | ||
userId: string; | ||
apiKey: string; | ||
language: string; | ||
}): Promise<changeUserPreferencesOutcome>; | ||
} | ||
@@ -85,3 +109,4 @@ /** | ||
*/ | ||
export interface AuthorizationRequest { | ||
export declare type AuthorizationRequest = { | ||
type: "public"; | ||
organizationId: string; | ||
@@ -95,3 +120,11 @@ codeChallenge: string; | ||
responseType: "code"; | ||
} | ||
} | { | ||
type: "confidential"; | ||
organizationId: string; | ||
redirectUri?: string; | ||
scope: Scope[]; | ||
state: string; | ||
clientId: string; | ||
responseType: "code"; | ||
}; | ||
export declare type RequestAuthorizationResult = { | ||
@@ -109,2 +142,3 @@ outcome: "authorizationRequestAccepted"; | ||
export declare type TokenRequestWithAuthorizationCode = { | ||
type: "public"; | ||
organizationId: string; | ||
@@ -116,2 +150,10 @@ code: string; | ||
scope: Scope[]; | ||
} | { | ||
type: "confidential"; | ||
organizationId: string; | ||
code: string; | ||
clientSecret: string; | ||
redirectUri?: string; | ||
clientId: string; | ||
scope: Scope[]; | ||
}; | ||
@@ -145,3 +187,3 @@ export declare type TokenRequestWithRefreshToken = { | ||
outcome: "notRegistered"; | ||
reason: "emailAlreadyUsed" | "clientDoesNotExist" | "userInformationNotValid" | "emailNotValid" | "passwordNotCompliant"; | ||
reason: "emailAlreadyUsed" | "clientDoesNotExist" | "userInformationNotValid" | "emailNotValid" | "passwordNotCompliant" | "clientTypeNotValid"; | ||
}; | ||
@@ -178,3 +220,3 @@ export declare type RequestAuthCodeResult = { | ||
outcome: "notIssued"; | ||
reason: "clientDoesNotExist" | "notRegistered" | "authCodeNotGranted" | "authProcessNotStarted" | "authProcessEnded" | "codeChallengeMismatch"; | ||
reason: "clientDoesNotExist" | "notRegistered" | "authCodeNotGranted" | "authProcessNotStarted" | "authProcessEnded" | "codeChallengeMismatch" | "clientCredentialsNotValid"; | ||
}; | ||
@@ -198,5 +240,6 @@ export declare type IssueTokensFromRefreshTokenResult = { | ||
clientId: string; | ||
secret?: string; | ||
} | { | ||
outcome: "notRegistered"; | ||
reason: "alreadyExists" | "invalidApiKey"; | ||
reason: "invalidApiKey" | "invalidType"; | ||
}; | ||
@@ -210,2 +253,8 @@ export declare type RegisterExternalIdpResult = { | ||
}; | ||
export declare type SaveAuthConfigResult = { | ||
outcome: "saved"; | ||
} | { | ||
outcome: "notSaved"; | ||
reason?: "invalidApiKey" | "invalidExternalIdpId"; | ||
}; | ||
export declare type RevokeTokenResult = { | ||
@@ -248,3 +297,3 @@ outcome: "revoked"; | ||
outcome: "rejected"; | ||
reason: "userNotActive" | "userDoesNotExist" | "clientDoesNotExist" | "userIdpNotInternal"; | ||
reason: "userNotActive" | "userDoesNotExist" | "clientDoesNotExist" | "userIdpNotInternal" | "clientTypeNotValid"; | ||
}; | ||
@@ -317,2 +366,6 @@ declare type ChangePasswordAfterResetResult = { | ||
ignoreSSO?: boolean; | ||
groupOrTeam: { | ||
type: "group" | "team"; | ||
name: string; | ||
}; | ||
}; | ||
@@ -332,3 +385,3 @@ export declare type BaseInviteResult = { | ||
outcome: "rejected"; | ||
reason: "invalidApiKey"; | ||
reason: "invalidApiKey" | "emailDoesNotMatchSSOPatterns"; | ||
}; | ||
@@ -341,2 +394,3 @@ declare type CreateInvitedUserRequest = { | ||
backendSecret?: string; | ||
language: string; | ||
}; | ||
@@ -354,3 +408,3 @@ declare type CreateBackOfficeInvitedUserRequest = { | ||
outcome: "rejected"; | ||
reason?: "invalidToken" | "expiredToken" | "passwordNotCompliant" | "userInformationNotValid" | "userAlreadyConfirmed" | "userNotInvited" | "djangoBackendError" | "userNotSaved" | "passwordNotSet"; | ||
reason?: "invalidToken" | "expiredToken" | "passwordNotCompliant" | "userInformationNotValid" | "userAlreadyConfirmed" | "userNotInvited" | "djangoBackendError" | "userNotSaved" | "passwordNotSet" | "personalInformationNotSaved"; | ||
}; | ||
@@ -374,3 +428,3 @@ export declare type CheckInvitedUserInformationResult = { | ||
outcome: "failed"; | ||
reason: "emailDoesNotExist" | "clientDoesNotExist" | "authIdNotValid" | "userNotActive" | "idpNameNotValid" | "samlRequestError"; | ||
reason: "emailDoesNotExist" | "clientDoesNotExist" | "authIdNotValid" | "userNotActive" | "idpNameNotValid" | "samlRequestError" | "clientCredentialsAreNotValid"; | ||
}; | ||
@@ -391,2 +445,30 @@ declare type CheckInvitedUserIdpResult = { | ||
}; | ||
declare type RegisterSharedClientInput = { | ||
type: "public"; | ||
baseUri: string; | ||
loginPath: string; | ||
authenticationPath: string; | ||
confirmUserPath: string; | ||
confirmInvitePath: string; | ||
resetPasswordPath: string; | ||
samlCodeResponsePath: string; | ||
apiKey: string; | ||
} | { | ||
type: "confidential"; | ||
baseUri: string; | ||
authenticationPath: string; | ||
apiKey: string; | ||
}; | ||
declare type RenameUserOutcome = { | ||
outcome: "renamed"; | ||
} | { | ||
outcome: "notRenamed"; | ||
reason?: "userDoesNotExist" | "userInformationNotValid" | "invalidApiKey" | "informationNotChanged" | "emailNotUnique"; | ||
}; | ||
declare type changeUserPreferencesOutcome = { | ||
outcome: "changed"; | ||
} | { | ||
outcome: "notChanged"; | ||
reason: "preferencesNotSaved" | "invalidApiKey"; | ||
}; | ||
export {}; |
@@ -27,2 +27,3 @@ export declare type User = { | ||
export declare type AuthProcess = { | ||
clientType: "public"; | ||
organizationId: string; | ||
@@ -39,4 +40,15 @@ id: string; | ||
} | { | ||
clientType: "confidential"; | ||
organizationId: string; | ||
id: string; | ||
processState: "requested"; | ||
redirectUri: string; | ||
state: string; | ||
clientId: string; | ||
responseType: "code"; | ||
scope: Scope[]; | ||
} | { | ||
clientType: "public"; | ||
organizationId: string; | ||
id: string; | ||
processState: "granted" | "ended"; | ||
@@ -52,2 +64,14 @@ codeChallenge: string; | ||
scope: Scope[]; | ||
} | { | ||
clientType: "confidential"; | ||
organizationId: string; | ||
id: string; | ||
processState: "granted" | "ended"; | ||
userId: string; | ||
authorizationCode: string; | ||
redirectUri: string; | ||
state: string; | ||
clientId: string; | ||
responseType: "code"; | ||
scope: Scope[]; | ||
}; | ||
@@ -59,9 +83,6 @@ export interface Organization { | ||
} | ||
export interface RegisteredClient { | ||
export declare type RegisteredClient = { | ||
type: "public"; | ||
id: string; | ||
baseUri: string; | ||
schema: "http" | "https"; | ||
paths: ClientPaths; | ||
} | ||
export interface ClientPaths { | ||
loginPath: string; | ||
@@ -73,3 +94,9 @@ authenticationPath: string; | ||
samlCodeResponsePath: string; | ||
} | ||
} | { | ||
type: "confidential"; | ||
id: string; | ||
secret: string; | ||
baseUri: string; | ||
authenticationPath: string; | ||
}; | ||
export declare type Scope = "openid"; | ||
@@ -81,2 +108,3 @@ interface SAMLConfig { | ||
cert: string; | ||
rawXML: string; | ||
params?: Record<string, string>; | ||
@@ -99,7 +127,7 @@ } | ||
ssoMandatory: true; | ||
defaultSSOid: string; | ||
defaultSSOId: string; | ||
} | { | ||
ssoMandatory: false; | ||
defaultSSOid?: string; | ||
defaultSSOId?: string; | ||
}; | ||
export {}; |
@@ -21,3 +21,2 @@ (function (factory) { | ||
const baseUri = uriParams.baseUri; | ||
const schema = uriParams.schema; | ||
async function getLoggedInUser() { | ||
@@ -55,3 +54,3 @@ const authenticationTokens = await authenticationTokensRepository | ||
state: "notAuthenticated", | ||
loginUrl: `${schema}://${baseUri}/${organizationId}/${loginPath}`, | ||
loginUrl: `${baseUri}/${organizationId}/${loginPath}`, | ||
}; | ||
@@ -67,2 +66,3 @@ }, | ||
const result = await server.requestAuthorization({ | ||
type: "public", | ||
organizationId, | ||
@@ -72,3 +72,3 @@ codeChallenge: codePair.codeChallenge, | ||
scope: ["openid"], | ||
redirectUri: redirectUrl ?? `${schema}://${baseUri}`, | ||
redirectUri: redirectUrl ?? baseUri, | ||
codeChallengeMethod: "S256", | ||
@@ -97,3 +97,2 @@ clientId, | ||
} | ||
//TODO: Check in server if this user has SAML and redirect towards idp for authentication | ||
return await fabriqIdentityProvider.authenticate(id, organizationId, authId, credentials); | ||
@@ -118,2 +117,3 @@ }, | ||
const tokensResult = await server.issueTokensFromAuthorizationCode({ | ||
type: "public", | ||
clientId: id, | ||
@@ -124,3 +124,3 @@ code: authorizationCode, | ||
scope: ["openid"], | ||
redirectUri: redirectUri ?? `${schema}://${baseUri}`, | ||
redirectUri: redirectUri ?? baseUri, | ||
}); | ||
@@ -140,4 +140,3 @@ if (tokensResult.outcome === "notIssued") { | ||
outcome: "authenticationFinalized", | ||
redirectUrl: redirectUri ?? | ||
`${schema}://${baseUri}`, | ||
redirectUrl: redirectUri ?? baseUri, | ||
authenticationTokens, | ||
@@ -147,3 +146,3 @@ }; | ||
getLoggedInUser, | ||
async requestUserRegistration(organizationId, credentials) { | ||
async requestUserRegistration(organizationId, credentials, information) { | ||
const user = await getLoggedInUser(); | ||
@@ -153,3 +152,3 @@ if (user) { | ||
} | ||
return await server.registerUser(clientId, organizationId, credentials); | ||
return await server.registerUser(clientId, organizationId, credentials, information.firstName, information.lastName, information.language); | ||
}, | ||
@@ -320,3 +319,3 @@ async confirmRegistration(confirmationToken) { | ||
}, | ||
async confirmInvitedUser(password, firstName, lastName, invitationToken, backendSecret) { | ||
async confirmInvitedUser(password, firstName, lastName, invitationToken, language, backendSecret) { | ||
const user = await getLoggedInUser(); | ||
@@ -332,2 +331,3 @@ if (user) { | ||
invitationToken: invitationToken, | ||
language, | ||
}); | ||
@@ -340,3 +340,10 @@ }, | ||
} | ||
const userAuthResult = await server.checkUserIdp({ clientId: id, organizationId, emailAddress, authId, redirectUri }); | ||
const userAuthResult = await server.checkUserIdp({ | ||
type: "public", | ||
clientId: id, | ||
organizationId, | ||
emailAddress, | ||
authId, | ||
redirectUri, | ||
}); | ||
if (userAuthResult.outcome === "failed") { | ||
@@ -343,0 +350,0 @@ return { outcome: "notProvided", reason: userAuthResult.reason }; |
@@ -43,3 +43,3 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
async function createJwt(payload, key) { | ||
const header = { alg: "EdDSA", typ: "JWT" }; | ||
const header = { typ: "JWT", alg: "EdDSA" }; | ||
const headerStr = base64Url.encode(encoder.encode(JSON.stringify(header))); | ||
@@ -46,0 +46,0 @@ const payloadStr = base64Url.encode(encoder.encode(JSON.stringify(payload))); |
389506
10173