npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

teko-market-v1

v1.8.4-dev

Published

Merchant Marketplace Javascript Library for Web App Client

Downloads

322

Readme

About The Project

A Javascript Library for integrate Teko Market to Web Application.
Library contain 3 parts:

  • App Switcher
  • Authentication and Authorization (through TekoIAM SDK)
  • Redirect to Buy license plan screen

Getting started

import TekoMarket from "teko-market-v1";

const App = (props) => {
  if (TekoMarket.auth.user.isLoggedIn()) {
    return <HomePageView userInfo={TekoMarket.auth.user.getUserInfo()} />;
  }
  return <LoginView />;
};

const LoginView = (props) => (
  <p onClick={() => TekoMarket.auth.login()}>Login with TekoID</p>
);

Installation

Using NPM package

# With yarn
yarn add teko-market-v1

# With npm
npm install teko-market-v1

Then you can initiate the client using TekoMarket:

import TekoMarket from "teko-market-v1";

TekoMarket.auth.init({
  appId: "your-app-id",
  loginUri: "MM-login-uri",
  clientId: "your-client-id",
  redirectUri: "your-redirect-uri",
  oauthDomain: "https://oauth.develop.tekoapis.net",
}).then(() => {
  // The initial phase is finish.
  // Now you can do your logic.
});

which returns a promise and resolve after finish initiating.

Using CDN Link

You can also include JS SDK teko-market.min.js in your source code, then access the lib using window.TekoMarket.

<script src="https://unpkg.com/[email protected]/dist/bundle/teko-market.min.js"></script>
var configs = {
  appId: "<your-app-id>", // MM provides when register application
  clientId: "<your-client-id>", // MM provides when register client auth
  loginUri: "<MM-login-uri>", // MM Login Uri
  redirectUri: "<your-redirect-uri>", // App provides for redirect when login successfully.
  
};
window.TekoMarket.auth.init(config);

Usage

App Switcher

Using React component

Note You have to init TekoOauth2 or TekoMarket with scope merchant-bff to use this component

Usage

import TekoMarket from 'teko-market-v1';

const { AppSwitcher } = TekoMarket;

...
<AppSwitcher
  baseMMUrl="https://market.dev.teko.vn"
  apiMerchantBffUrl="https://merchant-bff.dev.tekoapis.net"
  apiMarketCoreUrl="https://market-core.dev.tekoapis.net"
/>

Component Props

| Name | Description | Required | Default | |:------------------|:------------------------------------------------------------------------------------------------------------------|:--------:|:-------------------------------------------------------------------------------------------------------------------------------| | baseMMUrl | Merchant Marketplace URL for login string | X | | | apiMerchantBffUrl | URL of API merchant-bff string | X | | | apiMarketCoreUrl | URL of API market core | X | | | placement | Position of menu item. There are: topLeft, topCenter, topRight, bottomLeft, bottomCenter, bottomRight | | bottomLeft | | customImageUrl | App Switcher Image URL string | | https://storage.googleapis.com/develop-teko-storage/media/image/2023/1/3/d422ac2f-2f5e-4da1-9bb2-398c3d971372/app-switcher.png | | dropdownStyles | Change existing style of dropdown React.CSSProperties | | | | imgDropdownStyles | Change existing style of dropdown image React.CSSProperties | | |

Using IFrame

<iframe
  id="app-switcher"
  title="app-switcher"
  name='{
    "parentOrigin": "<window.location.origin>"
    "align": "right | left" 
  }' // parentOrigin is required; align is optional with default value "left"
  src="<MARKET_WEB_DOMAIN>/app-switcher" // MM cung cấp cho App
  frameborder="0"
  scrolling="no"
  height="52px"
/>

Example:

<iframe
  id="app-switcher"
  title="app-switcher"
  name='{"parentOrigin": "https://market.dev.teko.vn","align":"right"}'
  src="https://market.dev.teko.vn/app-switcher"
  frameborder="0"
  scrolling="no"
  height="52px"
/>

Authentication and Authorization

async TekoMarket.auth.init(configs)

| configs key | Type | Default value | Required | |:------------------------|:-----------|:----------------------------------------|:--------:| | appId | string | | X | | loginUri | string | | X | | clientId | string | | | | oauthDomain | string | https://oauth.teko.vn | | | redirectUri | string | protocol//hostname:port | | | postLogoutRedirectUri | string | protocol//hostname:port | | | scopes | [string] | [] | | | silent | boolean | true | | | monitorSession | boolean | false | | | checkTokenRevoked | boolean | false | | | monitorSessionMethod | string | iframe or bff(if configure bffDomain) | | | bffDomain | string | null | |

  • appId: The ID of your application which you registered in Merchant Marketplace.
  • loginUri: Your application will redirect to this URI to login to Merchant Marketplace, then redirect to your application and attach your clientId after login successfully.
  • clientId: The ID of your client which you registered in Identity Teko. If clientId missing, TekoMarket will automatically retrieve this value from the URL query parameter clientId or from localstorage. However, if the client ID is still not available, TekoMarket will not initialize the IAM SDK.
  • redirectUri: Your client will redirect to this uri with authorization code value after user successfully logged in. This value should match exact with one of the redirect_uris you registered in IAM App.
  • postLogoutRedirectUri: Your client will redirect to this uri after user successfully logged out. This value should match exact with one of the post_logout_redirect_uris you registered in IAM App.
  • scopes: The scopes of your client.
  • oauthDomain: The TekoMarket domain to use SDK. If this value missing, TekoMarket will retrieve this value from URL query parameter 'authDomain' or localstorage.
  • silent: If the SDK auto renew access token silently when the current one is expired. Set false to turn off this feature (so user must re-login if access token is expired).
  • monitorSession: Set to true to able to listen to changes in user session.
  • monitorSessionMethod: Set value in option list ['bff','sessionId','iframe'] to choose the session monitoring method:
    • bff: use BFF flow to monitor your session
    • sessionId: using session id to monitor your current session. Besides, it can detect when other session id created.
    • iframe: the default method to monitor session state using iframe window
  • checkTokenRevoked: Set to true to call oauthDomain/userinfo endpoint to ensure the current cached token is not revoked.
  • bffDomain: Set to the URL of your BFF to use BFF flow. This parameter also acts as a flag to use BFF or not.

NOTE: For develop environment, please specific oauthDomain to https://oauth.develop.tekoapis.net

NOTE: For stage environment, please specific oauthDomain to https://oauth.stage.tekoapis.net

NOTE: TekoMarket.auth.init() function is an async function.


TekoMarket.auth.login

.login(redirectUri = null)

Redirect to Merchant Market Login page to start login process.

After login success, Merchant Market Login will redirect back to optional parameter redirectUri.

By default, it will redirect to redirectUri param in TekoMarket.auth.init function.

Call this function when user click to Login button in your application.

This value should match exact with one of the redirect_uris you registered in IAM App.

TekoMarket.auth.user

.isLoggedIn()

Return true if user is logged in, false if not.

async .loginSilent()

A promise return current user logged in OAuth server with latest info and new access token. Raise if there is not logged user in OAuth server.

.logout(redirectUri = null)

Clear current user's info and log user out.

After logout success, Teko Identity OAuth Login will redirect back to optional parameter redirectUri.

By default, it will redirect to postLogoutRedirectUri param in TekoMarket.auth.init function.

Call this function when user click to Logout button in your application.

This value should match exact with one of the post_logout_redirect_uris you registered in IAM UI.

.loadUser()

Load current cache user in storage. Return undefined if there is not any user in cache storage.

Return value example:

{
  accessToken: 'random-string',
  expiresAt: 1595500000,
  expiresIn: 3600,
  idToken: 'jwt-string',
  profile: {
    sub: 'string',
    name: 'string',
    picture: 'url-string',
  },
  scopes: ['openid', 'profile'],
  sessionState: 'random-string',
  tokenType: 'Bearer'
}

NOTE: This function might return an user with expired accessToken.

.unloadUser()

Remove current cache user in storage.

.getAccessToken()

Get logged user's current access token.

Return a string which is current user's access token if user is logged. undefined if user is not logged.

NOTE: Since the access token can be renew silently after the current is expired (init with slient: true), be sure that you always use the current access token (not the old one).

import axios from "axios";
import TekoMarket from "teko-market-v1";

// Bad
const axiosInstance = axios.create({
  headers: {
    Authorization: `Bearer ${TekoMarket.auth.user.getAccessToken()}`,
  },
});

// The access token always same
axiosInstance.get("/api/resources");

// Good
axios.get("/api/resources", {
  headers: {
    Authorization: `Bearer ${TekoMarket.auth.user.getAccessToken()}`,
  },
}); // Now the token is fetch each time a request is made

// Better
const axiosInstance = axios.create();
axiosInstance.interceptors.request.use(
  (config) => {
    config.headers.Authorization = `Bearer ${TekoMarket.auth.user.getAccessToken()}`;
    return config;
  },
  (error) => Promise.reject(error)
);
axiosInstance.get("/api/resources");

NOTE: You should treat access token as a random string, even when OAuth server return this token in some specific forms (like JWT).

.getUserInfo()

Get current user's general information.

Return object which includes current user's information. Return undefined if user is not logged or openid not in scopes.

  • With openid scope, id_token will return with fields: sub, name, picture, updated_at.

  • With addition profile scope, id_token will return with addition fields: email, phone_number, birthday, address.

Return value example (with openid, profile, read:permissions included in scopes):

{
  sub: 'user_unique_id',
  name: 'User Name',
  picture: 'https://domain.com/avatar_url.jpg',

  email: '[email protected]',
  phone_number: '0123456789',
  birthday: '2000-12-31',
  address: 'Yume street',
}

async .getFullUserInfo(adminDomain = null)

Send HTTP request to get current user's full information.

Return object which includes current user's information. Return undefined if user is not logged or access token is expired. Return {message: null} current access token is invalid (revoked).

The response is as same as .getUserInfo() response, with addition read:permissions scope:

  • With addition read:permissions scope, response will return with addition fields: roles, permissions, meta_data.

Return value example (with openid, profile, read:permissions included in scopes):

{
  sub: 'user_unique_id',
  name: 'User Name',
  picture: 'https://domain.com/avatar_url.jpg',
  updated_at: '2019-12-31 00:00:00',

  email: '[email protected]',
  phone_number: '0123456789',
  birthday: '2000-12-31',
  address: 'Yume street',

  roles: ['string'],
  permissions: ['string'],
  meta_data: { key: 'value' }
}

WARNING: Calling getFullUserInfo() without specific adminDomain may lead to incorrect data.

For Teko OAuth, the adminDomain is auto-detected from oauthDomain. For other OAuth (Digilife OAuth), please specific this parameter.

This parameter is needed because of the limitation in current OAuth server when refresh user's access control data. This may be changed in later version.

.getUserScopes()

Get logged user's scopes.

Return array of string which is current user's scopes if user is logged. undefined if user is not logged.

Return value example:

["openid", "profile"];

NOTE: This scopes may different with the scopes you defined when init. Because the scopes may be able to access by your app, but not for the current user (the user denied the app for access his/her data). If you want to use scopes in order to display correct UI, please use this scopes value.

.getAccessTokenExpiresAt()

Return timestamp when the access token expired. undefined if user is not logged.


TekoMarket.auth.user.events

Register callbacks and execute them whenever certain events raise.

Current supported events:

  • userLoaded: raised when a user session has been established (or re-established). Not raised when user is loaded from cache storage.
  • Depend on the monitoring session method applied, there are two events for session monitoring:
    • userSessionChanged: apply with BFF and iframe method, raised when user session state changed (session expired, session logged out)
    • userSessionIdChanged: apply with check session id method, raised when user session id changed (session expired, session logged out, user logged in at another location)
  • silentRenewError: raised when automatic silent renew has failed.
  • accessTokenExpiring: raised 5 minutes before the current access token expires.
  • accessTokenExpired: raised when current access token has expired.

You can register callbacks by add functions, or remove them if you no longer want to execute them.

Examples:

// Should only call after Teko.init has resolved
TekoMarket.auth.user.events.addUserSessionChanged(() => {
  alert("User session changed. Force user to re-login.");
  TekoMarket.auth.user.unloadUser();
  TekoMarket.auth.login();
});

TekoID.user.events.addUserSessionIdChanged(() => {
    alert('User session changed or user logged in at another location. Force user to re-login.')
    TekoID.user.unloadUser()
    TekoID.user.login()
})

TekoMarket.auth.user.events.addSilentRenewError((err) => {
  console.err("Silent renew error. Details:", err);
});

Redirect to Buy license plan screen

Redirect from Client to page buy lisence plan screen in Merchant Marketplace.

TekoMarket.licensePlan.initPayment(params)

| params key | Type | Required | | :------------- | :------- | :------- | | appId | string | Y | | merchantId | number | Y | | marketDomain | string | Y | | appName | string | | | successUrl | string | |

Examples:

import TekoMarket from "teko-market-v1";

// Redirect to domain market.dev.teko.vn to buy license plan, then redirect to pm-staff.dev.teko.vn/admin when payment successful

const params = {
  appId: 'd754e587270a44afa0a57f9c5069c3f1',
  merchantId: 9,
  marketDomain: 'https://market.dev.teko.vn/',
  appName: "Landing Builder",
  successUrl: "https://pm-staff.dev.teko.vn/admin"
};

...

TekoMarket.licensePlan.initPayment(params);