Skip to content

v2.5 - Not yet released

More details can be found in the related milestone on GitHub.

Major breaking changes

💥 Exposed properties changed in composable activity.js. state, options and name properties are now exposed using a more global object CurrentActivityContext which is reactive (see https://github.com/kalisio/kdk/issues/1055).

TIP

To retrieve the state of the CurrentActivity you can now proceed that way:

js
const { CurrentActivityContext } = useCurrentActivity()
const { state } = CurrentActivityContext

WARNING

When using the composable activity.js from an another composable be aware that the CurrentActivity is not set and the CurrentActivityContext exposed properties are null. You should watch the CurrentActivity value to use the CurrentActivityContextobject.

💥 Renamed composable file counter.js to collection-counter.js. Therefore, the useCounter function is renamed to useCollectionCounter.

Major new features

👉 New KRequestProgressBar component to be used in your App.vue or equivalent in order to display a progress bar whenever a request to the server is processing.

👉 New useErrors() composable to be used in your App.vue or equivalent in order to display a notification whenever a request to the server raises an error.

👉 Ability for JWTs to target a user using others properties than the user ID, applications should allow this in their authentication configuration otherwise the default behavior still relies on the user ID.

⬇️ Example of an authentication configuration to allow JWT identifying a user by email
js
// default.js of your application, assuming your user objects have an email properties
authentication: {
	identityFields: ['email'],
	...
}

Your JWT can now be issued as usual but using a payload like this:

json
{
  "aud": "kalisio.xyz",
  "iss": "kalisio",
  "exp": 1552402010,
  "sub": "user_email@gmail.com"
}

👉 New KOAuthLoginScreen and KOAuthLogouScreen components to be used in your app when relying on an OAuth provider instead of local authentication.

⬇️ Example of configurations to be used to allow single login/logout with a keycloak provider
js
// frontend route.js of your application
{
  login: 'screen/KOAuthLoginScreen',
  'logout/:provider?': {
    name: 'logout',
    component: 'screen/KOAuthLogoutScreen',
    ...
  },
  ...
}
// frontend default.js of your application
screens: {
  login: {
    actions: [
      { id: 'keycloak-link', label: 'screen.LOGIN_WITH_KEYCLOAK', renderer: 'form-button', route: { url: '/oauth/keycloak' } }
    ]
  }
},
leftPane: {
  content: [
    ...,
    { id: 'logout', icon: 'las la-sign-out-alt', label: 'sideNav.LOGOUT', route: { name: 'logout', params: { provider: 'keycloak' } }, renderer: 'item' }
  ]
},
...

// backend default.js of your application
authentication: {
  oauth: {
    keycloak: {
      ...,
      logout_url: `${keycloakBaseUrl}/logout`
    }
  }
  ...
}

👉 New logout custom method and related custom event that can be sent from server to connected clients whenever a user has logout from one client of your application.

⬇️ How you can call it to logout all clients
js
// channels.js of your application
app.on('logout', (authResult, { connection }) => {
  // connection can be undefined if there is no
  // real-time connection, e.g. when logging in via REST
  if (connection) {
    // Obtain the logged user from the connection
    const user = connection.user
    const usersService = app.getService('users')
    usersService.logout(user)
  }
})
const usersService = app.getService('users')
usersService.publish('logout', (data, hook) => {
  const user = data
  // Publish logout event to target user only
  return app.channel('authenticated').filter(connection => {
    const connectionUser = connection.user
    return user && connectionUser && connectionUser._id.toString() === user._id.toString()
  })
})

On the client side the session composable will listen to this event automatically to redirect the user to the logout page.

👉 The declareService client method should now be replaced by createService like on the server side in order to initialize the required services for your app upfront. The getService client method now relies on this declaration to return the appropriate service when not explicitely providing the context as input parameter.