diff --git a/ui/packages/consul-ui/app/components/jwt-source/README.mdx b/ui/packages/consul-ui/app/components/jwt-source/README.mdx
index 53e442525..cd8c602d5 100644
--- a/ui/packages/consul-ui/app/components/jwt-source/README.mdx
+++ b/ui/packages/consul-ui/app/components/jwt-source/README.mdx
@@ -1,27 +1,93 @@
----
-class: ember
----
# JwtSource
-```hbs
-
+This is a Source-like component and with most of our Source components, the
+component only needs to be added to the page in order to start the flow and is
+meant to be used as such (think 'this is like an ``).
+
+The component will go through the steps of requesting a JWT token from a third
+party OAuth provider. `src` should contain the full URL of the authorization
+URL for the 3rd party provider including `redirect_uri`. Once the user has
+logged into the 3rd party provider the `onchange` event will be fired
+containing an event-like object whose data contains the JWT information.
+
+During development you can use the `CONSUL_OIDC_PROVIDER_URL`
+environment/cookie value to inject/mock the provider URL of your choice. This
+var/cookie value **does not** need the `redirect_uri` parameter adding as that
+will be automatically added by the UI . This URL will then be returned by our
+mock API when requesting the AuthURL for **all** OIDC AuthMethods.
+
+This component **does not store the resulting JWT**, it only emits it via
+its `onchange` argument/event handler. Errors are emitted via the `onerror`
+argument/event handler.
+
+
+```hbs preview-template
+
+
+
+
```
-### Arguments
+## Arguments
| Argument | Type | Default | Description |
| --- | --- | --- | --- |
-| `src` | `String` | | The source to subscribe to updates to, this should map to a string based URI |
-| `onchange` | `Function` | | The action to fire when the data changes. Emits an Event-like object with a `data` property containing the jwt data, in this case the autorizationCode and the status |
+| `src` | `String` | | The **full** AuthURL for the 3rd party OIDC provider as provided by Consul (including `redirect_uri`) |
+| `onchange` | `Function` | | The action to fire when the data changes. Emits an Event-like object with a `data` property containing the JWT data, in this case the `autorizationStatus`, `autorizationCode`, plus the UI added `provider` name |
| `onerror` | `Function` | | The action to fire when an error occurs. Emits ErrorEvent object with an `error` property containing the Error. |
-This component will go through the steps of requesting a JWT token from a third party oauth provider. `src` should contain the full URL of the authorization URL for the 3rd party provider. Once the user has logged into the 3rd party provider the `onchange` event will be fired containing an event-like object whose data contains the JWT information.
-The component need only be place into the DOM in order to begin the OAuth dance.
-
-### See
+## See
- [Component Source Code](./index.js)
-- [Template Source Code](./index.hbs)
---
diff --git a/ui/packages/consul-ui/app/components/jwt-source/index.js b/ui/packages/consul-ui/app/components/jwt-source/index.js
index c4da73b58..664e5fcf7 100644
--- a/ui/packages/consul-ui/app/components/jwt-source/index.js
+++ b/ui/packages/consul-ui/app/components/jwt-source/index.js
@@ -1,31 +1,46 @@
-import Component from '@ember/component';
+import Component from '@glimmer/component';
import { inject as service } from '@ember/service';
+
import { fromPromise } from 'consul-ui/utils/dom/event-source';
-export default Component.extend({
- repo: service('repository/oidc-provider'),
- dom: service('dom'),
- tagName: '',
- onchange: function(e) {},
- onerror: function(e) {},
- init: function() {
- this._super(...arguments);
- this._listeners = this.dom.listeners();
- },
- willDestroyElement: function() {
- this._super(...arguments);
- this.repo.close();
- this._listeners.remove();
- },
- didInsertElement: function() {
+// TODO: We could probably update this to be a template only component now
+// rather than a JS only one.
+export default class JWTSource extends Component {
+ @service('repository/oidc-provider') repo;
+ @service('dom') dom;
+
+ constructor() {
+ super(...arguments);
if (this.source) {
this.source.close();
}
+ this._listeners = this.dom.listeners();
// TODO: Could this use once? Double check but I don't think it can
- this.source = fromPromise(this.repo.findCodeByURL(this.src));
+ this.source = fromPromise(this.repo.findCodeByURL(this.args.src));
this._listeners.add(this.source, {
message: e => this.onchange(e),
error: e => this.onerror(e),
});
- },
-});
+ }
+
+ onchange(e) {
+ if(typeof this.args.onchange === 'function') {
+ this.args.onchange(...arguments);
+ }
+ }
+
+ onerror(e) {
+ if(typeof this.args.onerror === 'function') {
+ this.args.onerror(...arguments);
+ }
+ }
+
+ willDestroy() {
+ super.willDestroy(...arguments);
+ if (this.source) {
+ this.source.close();
+ }
+ this.repo.close();
+ this._listeners.remove();
+ }
+}
diff --git a/ui/packages/consul-ui/app/components/token-source/README.mdx b/ui/packages/consul-ui/app/components/token-source/README.mdx
index 03a2facd3..8a451f2c8 100644
--- a/ui/packages/consul-ui/app/components/token-source/README.mdx
+++ b/ui/packages/consul-ui/app/components/token-source/README.mdx
@@ -1,36 +1,89 @@
----
-class: ember
----
-## TokenSource
+# TokenSource
-```hbs
- `). It is also loosely based on a HTML ``
+element (it has `type` and `value` arguments/attributes)
+
+When using the `oidc` type the component will go through the steps of
+requesting the OIDC providers authorization URL from Consul, go through the
+OIDC flow with the user and the 3rd party provider (via our ``
+component), then lastly exchanging the resulting JWT with Consul for a normal
+Consul token.
+
+When using the `secret` type, the component simply exchanges the users secret
+for a normal Consul token.
+
+This component **does not store the resulting token**, it only emits it via
+its `onchange` argument/event handler. Errors are emitted via the `onerror`
+argument/event handler.
+
+```hbs preview-template
+
+
+
+
```
-### Arguments
+## Arguments
| Argument | Type | Default | Description |
| --- | --- | --- | --- |
| `dc` | `String` | | The name of the current datacenter |
| `nspace` | `String` | | The name of the current namespace |
| `partition` | `String` | | The name of the current partition |
+| `type` | `String` | | `secret` or `oidc`. `secret` is just traditional login, whereas `oidc` uses the users OIDC provider |
+| `value` | `String` | | When `type` is `secret` this should be the users secret. When `type` is `oidc` this should be the name of the `AuthMethod` to use for authentication |
| `onchange` | `Function` | | The action to fire when the data changes. Emits an Event-like object with a `data` property containing the jwt data, in this case the autorizationCode and the status |
| `onerror` | `Function` | | The action to fire when an error occurs. Emits ErrorEvent object with an `error` property containing the Error. |
-This component will go through the steps of requesting a JWT token from a third party oauth provider. `src` should contain the full URL of the authorization URL for the 3rd party provider. Once the user has logged into the 3rd party provider the `onchange` event will be fired containing an event-like object whose data contains the JWT information.
-The component need only be place into the DOM in order to begin the OAuth dance.
-
-### See
+## See
+- [JwtSource Component](../jwt-source/README.mdx)
+- [StateChart](./chart.xstate.js)
- [Component Source Code](./index.js)
- [Template Source Code](./index.hbs)
diff --git a/ui/packages/consul-ui/app/components/token-source/index.hbs b/ui/packages/consul-ui/app/components/token-source/index.hbs
index 30224b669..94186be1b 100644
--- a/ui/packages/consul-ui/app/components/token-source/index.hbs
+++ b/ui/packages/consul-ui/app/components/token-source/index.hbs
@@ -1,44 +1,60 @@
-
-
- {{!-- This `or` can be completely removed post 1.10 as 1.10 has optional params with default values --}}
- {{#let (concat '/' (or partition '') '/' (or nspace '') '/' dc) as |path|}}
+
+
+ {{#let
+ (uri '/${partition}/{$nspace}/${dc}'
+ (hash
+ partition=@partition
+ nspace=@nspace
+ dc=@dc
+ )
+ )
+ as |path|}}
{{/let}}
diff --git a/ui/packages/consul-ui/app/components/token-source/index.js b/ui/packages/consul-ui/app/components/token-source/index.js
index c0ad688c5..1eb317369 100644
--- a/ui/packages/consul-ui/app/components/token-source/index.js
+++ b/ui/packages/consul-ui/app/components/token-source/index.js
@@ -1,37 +1,47 @@
-import Component from '@ember/component';
+import Component from '@glimmer/component';
+import { action } from '@ember/object';
+import { tracked } from '@glimmer/tracking';
import chart from './chart.xstate';
-export default Component.extend({
- onchange: function() {},
- init: function() {
- this._super(...arguments);
+
+export default class TokenSource extends Component {
+ @tracked provider;
+ @tracked jwt;
+
+ constructor() {
+ super(...arguments);
this.chart = chart;
- },
- actions: {
- isSecret: function() {
- return this.type === 'secret';
- },
- change: function(e) {
- e.data.toJSON = function() {
- return {
- AccessorID: this.AccessorID,
- // TODO: In the past we've always ignored the SecretID returned
- // from the server and used what the user typed in instead, now
- // as we don't know the SecretID when we use SSO we use the SecretID
- // in the response
- SecretID: this.SecretID,
- Namespace: this.Namespace,
- Partition: this.Partition,
- ...{
- AuthMethod: typeof this.AuthMethod !== 'undefined' ? this.AuthMethod : undefined,
- // TODO: We should be able to only set namespaces if they are enabled
- // but we might be testing for nspaces everywhere
- // Namespace: typeof this.Namespace !== 'undefined' ? this.Namespace : undefined
- },
- };
+ }
+
+ @action
+ isSecret() {
+ return this.args.type === 'secret';
+ }
+
+ @action
+ change(e) {
+ e.data.toJSON = function() {
+ return {
+ AccessorID: this.AccessorID,
+ // TODO: In the past we've always ignored the SecretID returned
+ // from the server and used what the user typed in instead, now
+ // as we don't know the SecretID when we use SSO we use the SecretID
+ // in the response
+ SecretID: this.SecretID,
+ Namespace: this.Namespace,
+ Partition: this.Partition,
+ ...{
+ AuthMethod: typeof this.AuthMethod !== 'undefined' ? this.AuthMethod : undefined,
+ // TODO: We should be able to only set namespaces if they are enabled
+ // but we might be testing for nspaces everywhere
+ // Namespace: typeof this.Namespace !== 'undefined' ? this.Namespace : undefined
+ },
};
- // TODO: We should probably put the component into idle state
- this.onchange(e);
- },
- },
-});
+ };
+ // TODO: We should probably put the component into idle state
+ if(typeof this.args.onchange === 'function') {
+ this.args.onchange(e);
+ }
+ }
+
+}