init method

Future init(
  1. String tag,
  2. String configFileName
)

Init B2C application. It look for existing accounts and retrieves information.

The tag argument is used to distinguish which invocation of the init generated the return callback. The configFileName argument specifies the name of the json configuration file in the web/assets folder.

Returns a Future callable from the AzureB2C plugin.

It emits a B2COperationResult with possible results:

Implementation

Future init(String tag, String configFileName) async {
  initializeDateFormatting();

  try {
    var conf = json.decode(await rootBundle.loadString(configFileName));

    BrowserCacheLocation cache = BrowserCacheLocation.sessionStorage;
    if (conf.containsKey("cache_location")) {
      if (conf["cache_location"] == "localStorage")
        cache = BrowserCacheLocation.localStorage;
      else if (conf["cache_location"] == "memoryStorage")
        cache = BrowserCacheLocation.memoryStorage;
    }

    String clientId = conf["client_id"];
    String redirectURI = conf["redirect_uri"];

    if (conf.containsKey("interaction_mode")) {
      if (conf["interaction_mode"] == "redirect")
        _interactionMode = B2CInteractionMode.REDIRECT;
    }

    String? defaultAuthority;
    List<String> authorities = <String>[];
    if (conf.containsKey("authorities")) {
      for (Map<String, dynamic> authority in conf["authorities"]) {
        if (authority.containsKey("default") &&
            authority["default"] == true) {
          defaultAuthority = authority["authority_url"];
        }
        authorities.add(authority["authority_url"]);
      }
    }
    _setHostAndTenantFromAuthority(defaultAuthority!);

    if (conf.containsKey("default_scopes")) {
      for (String scope in conf["default_scopes"]) {
        _defaultScopes.add(scope);
      }
    }

    _configuration = Configuration()
      ..cache = (CacheOptions()..cacheLocation = cache)
      ..auth = (BrowserAuthOptions()
        ..authority = defaultAuthority
        ..clientId = clientId
        ..redirectUri = redirectURI
        ..knownAuthorities = authorities);

    _b2cApp = PublicClientApplication(_configuration!);
    _loadAllAccounts();

    if (window.localStorage.containsKey(_B2C_PLUGIN_LAST_ACCESS)) {
      try {
        B2CAccessToken lastAccessToken = B2CAccessToken.fromJson(
            json.decode(window.localStorage[_B2C_PLUGIN_LAST_ACCESS]!));
        if (_users.containsKey(lastAccessToken.subject)) {
          _accessTokens[lastAccessToken.subject] = lastAccessToken;
          _emitCallback(B2COperationResult(
              tag,
              B2COperationSource.POLICY_TRIGGER_INTERACTIVE,
              B2COperationState.SUCCESS));
        }
      } catch (exception) {
        log("SessionStorage temp access token parse failed: $exception",
            name: tag);
      } finally {
        window.localStorage.remove(_B2C_PLUGIN_LAST_ACCESS);
      }
    }

    if (_lastHash != null && _lastHash != "#/") {
      if (_lastHash!.contains(_B2C_PASSWORD_CHANGE)) {
        window.sessionStorage
            .removeWhere((key, value) => key.startsWith("msal"));

        _emitCallback(B2COperationResult(
            tag,
            B2COperationSource.POLICY_TRIGGER_INTERACTIVE,
            B2COperationState.PASSWORD_RESET));
        return;
      } else {
        var result = await _b2cApp!.handleRedirectFuture(_lastHash);
        if (result != null) {
          _users[result.uniqueId] = result.account!;
          _accessTokens[result.uniqueId] = _accessTokenFromAuthResult(result);

          // MSAL seams to reload the page after the handleRedirectFuture is
          // completed, so we temporarly store the access token in the local
          // storage to use it later, e.g. see code before.
          window.localStorage[_B2C_PLUGIN_LAST_ACCESS] =
              json.encode(_accessTokenFromAuthResult(result));
        }
      }

      _lastHash = null;
    }

    _emitCallback(B2COperationResult(
        tag, B2COperationSource.INIT, B2COperationState.SUCCESS));
  } catch (ex) {
    _emitCallback(B2COperationResult(
        tag, B2COperationSource.INIT, B2COperationState.CLIENT_ERROR));
  }
}