Skip to content

Commit 64f0618

Browse files
authored
Merge pull request #3305 from ably/fix/anchor-double-hash
[DX-998] fix: remove spurious # from anchor IDs and harden headers hook
2 parents 815615d + fc30aff commit 64f0618

6 files changed

Lines changed: 78 additions & 75 deletions

File tree

src/components/Layout/mdx/headers.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ export const useCopyableHeaders = () => {
1616

1717
// Prioritize name attribute, fall back to href
1818
if (firstAnchor.hasAttribute('id')) {
19-
header.setAttribute('href', `#${firstAnchor.getAttribute('id')}`);
19+
const rawId = firstAnchor.getAttribute('id') ?? '';
20+
const id = rawId.startsWith('#') ? rawId.slice(1) : rawId;
21+
header.setAttribute('href', `#${id}`);
2022
} else if (firstAnchor.hasAttribute('href')) {
2123
header.setAttribute('href', firstAnchor.getAttribute('href') || '');
2224
}
@@ -42,7 +44,8 @@ export const useCopyableHeaders = () => {
4244

4345
if (firstAnchor?.hasAttribute('id')) {
4446
// First priority: name attribute on first anchor
45-
anchor = `#${firstAnchor.getAttribute('id')}`;
47+
const rawId = firstAnchor.getAttribute('id') ?? '';
48+
anchor = `#${rawId.startsWith('#') ? rawId.slice(1) : rawId}`;
4649
} else if (firstAnchor?.hasAttribute('href')) {
4750
// Second priority: href attribute on first anchor
4851
anchor = firstAnchor.getAttribute('href') || '';

src/pages/docs/api/realtime-sdk/authentication.mdx

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,29 @@ redirect_from:
2323

2424
This is the Authentication API Reference.
2525

26-
## Tokens <a id="#tokens" />
26+
## Tokens <a id="tokens" />
2727

2828
In the documentation, references to Ably-compatible tokens typically refer either to an Ably Token, or an [Ably JWT](#ably-jwt). For Ably Tokens, this can either be referring to the `TokenDetails` object that contain the `token` string or the token string itself. `TokenDetails` objects are obtained when [requesting an Ably Token](#request-token) from the Ably service and contain not only the `token` string in the `token` attribute, but also contain attributes describing the properties of the Ably Token. For [Ably JWT](#ably-jwt), this will be simply referring to a JWT which has been signed by an Ably private API key.
2929

30-
## Auth object <a id="#auth-object" />
30+
## Auth object <a id="auth-object" />
3131

3232
The principal use-case for the `Auth` object is to create Ably [`TokenRequest`](#token-request) objects with [createTokenRequest](#create-token-request) or obtain [Ably Tokens](#token-details) from Ably with [requestToken](#request-token), and then issue them to other "less trusted" clients. Typically, your servers should be the only devices to have a [private API key](/docs/auth#api-key), and this private API key is used to securely sign Ably [`TokenRequest`](#token-request) objects or request [Ably Tokens](#token-details) from Ably. Clients are then issued with these short-lived [Ably Tokens](#token-details) or Ably [`TokenRequest`](#token-request) objects, and the libraries can then use these to authenticate with Ably. If you adopt this model, your private API key is never shared with clients directly.
3333

3434
A subsidiary use-case for the `Auth` object is to preemptively trigger renewal of a token or to acquire a new token with a revised set of capabilities by explicitly calling <If lang="javascript,nodejs,java,objc,ruby,swift">[`authorize`](#authorize)</If><If lang="csharp">[`Authorize`](#authorize)</If>.
3535

3636
The Auth object is available as the <If lang="java">[`auth` field](/docs/api/realtime-sdk#auth)</If><If lang="csharp">[`Auth` property](/docs/api/realtime-sdk#auth)</If><If lang="javascript,nodejs,objc,swift">[`auth` property](/docs/api/realtime-sdk#auth)</If><If lang="ruby">[`auth` attribute](/docs/api/realtime-sdk#auth)</If> of an [Ably Realtime client instance](/docs/api/realtime-sdk#constructor).
3737

38-
## <If lang="javascript,nodejs">Auth Properties</If><If lang="java">io.ably.lib.rest.Auth Members</If><If lang="csharp">IO.Ably.AblyAuth Properties</If><If lang="ruby">Ably::Auth Attributes</If><If lang="objc,swift">ARTAuth Properties</If> <a id="#properties" />
38+
## <If lang="javascript,nodejs">Auth Properties</If><If lang="java">io.ably.lib.rest.Auth Members</If><If lang="csharp">IO.Ably.AblyAuth Properties</If><If lang="ruby">Ably::Auth Attributes</If><If lang="objc,swift">ARTAuth Properties</If> <a id="properties" />
3939

4040
The <If lang="objc,swift">`ART`</If>`Auth` object exposes the following public <If lang="javascript,nodejs,csharp,objc,swift">properties</If><If lang="ruby">attributes</If><If lang="java">members</If>:
4141

42-
### <If lang="javascript,nodejs,java,objc,swift">clientId</If><If lang="ruby">client_id</If><If lang="csharp">ClientId</If> <a id="#client-id" />
42+
### <If lang="javascript,nodejs,java,objc,swift">clientId</If><If lang="ruby">client_id</If><If lang="csharp">ClientId</If> <a id="client-id" />
4343

4444
The client ID string, if any, configured for this client connection. See [identified clients](/docs/auth/identified-clients) for more information on trusted client identifiers.
4545

46-
## <If lang="javascript,nodejs">Auth Methods</If><If lang="java">io.ably.lib.rest.Auth Methods</If><If lang="csharp">IO.Ably.AblyAuth Methods</If><If lang="ruby">Ably::Auth Methods</If><If lang="objc,swift">ARTAuth Methods</If> <a id="#methods" />
46+
## <If lang="javascript,nodejs">Auth Methods</If><If lang="java">io.ably.lib.rest.Auth Methods</If><If lang="csharp">IO.Ably.AblyAuth Methods</If><If lang="ruby">Ably::Auth Methods</If><If lang="objc,swift">ARTAuth Methods</If> <a id="methods" />
4747

48-
### <If lang="javascript,nodejs,java,ruby,objc,swift">authorize</If><If lang="csharp">Authorize</If> <a id="#authorize" />
48+
### <If lang="javascript,nodejs,java,ruby,objc,swift">authorize</If><If lang="csharp">Authorize</If> <a id="authorize" />
4949

5050
<If lang="javascript,nodejs">
5151

@@ -267,7 +267,7 @@ client.auth.authorize(tokenParams, options: nil) { tokenDetails, error in
267267

268268
</If>
269269

270-
### <If lang="javascript,nodejs,java,objc,swift">createTokenRequest</If><If lang="ruby">create_token_request</If><If lang="csharp">CreateTokenRequestAsync</If> <a id="#create-token-request" />
270+
### <If lang="javascript,nodejs,java,objc,swift">createTokenRequest</If><If lang="ruby">create_token_request</If><If lang="csharp">CreateTokenRequestAsync</If> <a id="create-token-request" />
271271

272272
<If lang="javascript,nodejs">
273273

@@ -480,7 +480,7 @@ client.auth.createTokenRequest(tokenParams, options: nil) { tokenRequest, error
480480

481481
</If>
482482

483-
### <If lang="javascript,nodejs,java,objc,swift">requestToken</If><If lang="ruby">request_token</If><If lang="csharp">RequestTokenAsync</If> <a id="#request-token" />
483+
### <If lang="javascript,nodejs,java,objc,swift">requestToken</If><If lang="ruby">request_token</If><If lang="csharp">RequestTokenAsync</If> <a id="request-token" />
484484

485485
<If lang="javascript,nodejs">
486486

@@ -704,7 +704,7 @@ client.auth.requestToken(tokenParams, withOptions: : nil) { tokenDetails, error
704704

705705
<If lang="javascript,nodejs">
706706

707-
### revokeTokens <a id="#revoke-tokens" />
707+
### revokeTokens <a id="revoke-tokens" />
708708

709709
`revokeTokens(TokenRevocationTargetSpecifier[] specifiers, TokenRevocationOptions options?): Promise<BatchResult<TokenRevocationSuccessResult | TokenRevocationFailureResult>>`
710710

@@ -761,9 +761,9 @@ try {
761761

762762
</If>
763763

764-
## Related types <a id="#related-types" />
764+
## Related types <a id="related-types" />
765765

766-
### <If lang="javascript,nodejs,csharp">AuthOptions Object</If><If lang="objc,swift">ARTAuthOptions</If><If lang="ruby">AuthOptions Hash</If><If lang="java">io.ably.lib.rest.Auth.AuthOptions</If> <a id="#auth-options" />
766+
### <If lang="javascript,nodejs,csharp">AuthOptions Object</If><If lang="objc,swift">ARTAuthOptions</If><If lang="ruby">AuthOptions Hash</If><If lang="java">io.ably.lib.rest.Auth.AuthOptions</If> <a id="auth-options" />
767767

768768
<If lang="javascript,nodejs">
769769

@@ -803,7 +803,7 @@ try {
803803
| <If lang="javascript,nodejs,java,objc,swift">queryTime</If><If lang="csharp,go">QueryTime</If><If lang="ruby">:query_time</If> | _false_ If true, the library will query the Ably servers for the current time when [issuing TokenRequests](/docs/auth/token) instead of relying on a locally-available time of day. Knowing the time accurately is needed to create valid signed Ably [TokenRequests](/docs/auth/token), so this option is useful for library instances on auth servers where for some reason the server clock cannot be kept synchronized through normal means, such as an [NTP daemon](https://en.wikipedia.org/wiki/Ntpd) . The server is queried for the current time once per client library instance (which stores the offset from the local clock), so if using this option you should avoid instancing a new version of the library for each request. | `Boolean` |
804804
| <If lang="javascript,nodejs,java,objc,swift">token</If><If lang="csharp,go">Token</If><If lang="ruby">:token</If> | An authentication token. This can either be a [`TokenDetails`](/docs/api/realtime-sdk/types#token-details) object, a [`TokenRequest`](/docs/api/realtime-sdk/types#token-request) object, or token string (obtained from the <If lang="javascript,nodejs,java,objc,swift">`token`</If><If lang="csharp,go">`Token`</If> property of a [`TokenDetails`](/docs/api/realtime-sdk/types#token-details) component of an Ably TokenRequest response, or a [JSON Web Token](https://tools.ietf.org/html/rfc7519) satisfying [the Ably requirements for JWTs](/docs/auth/token/jwt)). This option is mostly useful for testing: since tokens are short-lived, in production you almost always want to use an authentication method that allows the client library to renew the token automatically when the previous one expires, such as <If lang="javascript,nodejs,java,objc,swift">`authUrl`</If><If lang="csharp">AuthUrl</If><If lang="ruby">:auth_url</If><If lang="python">auth_url</If> or <If lang="javascript,nodejs,java,objc,swift">authCallback</If><If lang="csharp">AuthCallback</If><If lang="python">auth_callback</If><If lang="ruby">:auth_callback</If>. Read more about [Token authentication](/docs/auth/token) | `String`, `TokenDetails` or `TokenRequest` |
805805

806-
### <If lang="javascript,nodejs">TokenDetails Object</If><If lang="objc,swift">ARTTokenDetails</If><If lang="java">io.ably.lib.types.TokenDetails</If><If lang="ruby">Ably::Models::TokenDetails</If><If lang="csharp">IO.Ably.TokenDetails</If> <a id="#token-details" />
806+
### <If lang="javascript,nodejs">TokenDetails Object</If><If lang="objc,swift">ARTTokenDetails</If><If lang="java">io.ably.lib.types.TokenDetails</If><If lang="ruby">Ably::Models::TokenDetails</If><If lang="csharp">IO.Ably.TokenDetails</If> <a id="token-details" />
807807

808808
`TokenDetails` is a type providing details of Ably Token string and its associated metadata.
809809

@@ -838,7 +838,7 @@ try {
838838

839839
### TokenDetails constructors
840840

841-
#### <If lang="javascript,nodejs,java,csharp,objc,swift">TokenDetails.fromJson</If><If lang="ruby">TokenDetails.from_json</If> <a id="#token-details-from-json" />
841+
#### <If lang="javascript,nodejs,java,csharp,objc,swift">TokenDetails.fromJson</If><If lang="ruby">TokenDetails.from_json</If> <a id="token-details-from-json" />
842842

843843
<If lang="javascript,nodejs,java,csharp,objc,swift">
844844

@@ -864,7 +864,7 @@ A <If lang="javascript,nodejs,java,csharp,objc,ruby">static factory method</If>
864864

865865
A [`TokenDetails`](/docs/api/realtime-sdk/types#token-details) object
866866

867-
### <If lang="javascript,nodejs">TokenParams Object</If><If lang="objc,swift">ARTTokenParams</If><If lang="ruby">TokenParams Hash</If><If lang="java">io.ably.lib.rest.Auth.TokenParams</If><If lang="csharp">IO.Ably.TokenParams</If> <a id="#token-params" />
867+
### <If lang="javascript,nodejs">TokenParams Object</If><If lang="objc,swift">ARTTokenParams</If><If lang="ruby">TokenParams Hash</If><If lang="java">io.ably.lib.rest.Auth.TokenParams</If><If lang="csharp">IO.Ably.TokenParams</If> <a id="token-params" />
868868

869869
<If lang="javascript,nodejs">
870870

@@ -900,7 +900,7 @@ A [`TokenDetails`](/docs/api/realtime-sdk/types#token-details) object
900900
| <If lang="javascript,nodejs,java,objc,swift">timestamp</If><If lang="csharp">Timestamp</If><If lang="ruby">:timestamp</If> | <If lang="javascript,nodejs,java">The timestamp (in milliseconds since the epoch)</If><If lang="ruby,objc,swift,csharp">The timestamp</If> of this request. `timestamp`, in conjunction with the `nonce`, is used to prevent requests for [Ably Token](/docs/api/realtime-sdk/authentication#token-details) from being replayed. | <If lang="javascript,nodejs">`Integer`</If><If lang="java">`Long Integer`</If><If lang="ruby">`Time`</If><If lang="objc,swift">`NSDate`</If><If lang="csharp">`DateTimeOffset`</If><If lang="flutter">`DateTime`</If> |
901901
| <If lang="javascript,nodejs,java,objc,swift">ttl</If><If lang="csharp">Ttl</If><If lang="ruby">:ttl</If> | Requested time to live for the [Ably Token](/docs/api/realtime-sdk/authentication#token-details) being created <If lang="javascript,nodejs,java">in milliseconds</If><If lang="ruby">in seconds</If><If lang="objc,swift">as a `NSTimeInterval`</If><If lang="csharp">as a `TimeSpan`.</If> When omitted, the Ably REST API default of 60 minutes is applied by Ably. <br />_Default: 1 hour_ | <If lang="javascript,nodejs">`Integer` (milliseconds)</If><If lang="ruby">`Integer` (seconds)</If><If lang="objc,swift">`NSTimeInterval`</If><If lang="java">`Long Integer`</If><If lang="csharp">`TimeSpan`</If> |
902902

903-
### <If lang="javascript,nodejs">TokenRequest Object</If><If lang="objc,swift">ARTTokenRequest</If><If lang="ruby">Ably::Models::TokenRequest</If><If lang="java">io.ably.lib.rest.Auth.TokenRequest</If><If lang="csharp">IO.Ably.TokenRequest</If> <a id="#token-request" />
903+
### <If lang="javascript,nodejs">TokenRequest Object</If><If lang="objc,swift">ARTTokenRequest</If><If lang="ruby">Ably::Models::TokenRequest</If><If lang="java">io.ably.lib.rest.Auth.TokenRequest</If><If lang="csharp">IO.Ably.TokenRequest</If> <a id="token-request" />
904904

905905
`TokenRequest` is a type containing parameters for an Ably `TokenRequest`. [Ably Tokens](/docs/api/realtime-sdk/authentication#token-details) are requested using <If lang="javascript,nodejs,java,csharp,objc,swift">[Auth#requestToken](/docs/api/rest-sdk/authentication#request-token)</If><If lang="ruby">[Auth#request_token](/docs/api/rest-sdk/authentication#request-token)</If>
906906

@@ -918,7 +918,7 @@ A [`TokenDetails`](/docs/api/realtime-sdk/types#token-details) object
918918

919919
### TokenRequest constructors
920920

921-
#### <If lang="javascript,nodejs,java,csharp,objc,swift">TokenRequest.fromJson</If><If lang="ruby">TokenRequest.from_json</If><If lang="flutter">TokenRequest.fromMap</If> <a id="#token-request-from-json" />
921+
#### <If lang="javascript,nodejs,java,csharp,objc,swift">TokenRequest.fromJson</If><If lang="ruby">TokenRequest.from_json</If><If lang="flutter">TokenRequest.fromMap</If> <a id="token-request-from-json" />
922922

923923
<If lang="javascript,nodejs,java,csharp,objc,swift">
924924

@@ -944,7 +944,7 @@ A <If lang="javascript,nodejs,java,csharp,objc,swift,ruby">static factory method
944944

945945
A [`TokenRequest`](/docs/api/realtime-sdk/types#token-request) object
946946

947-
### Ably JWT <a id="#ably-jwt" />
947+
### Ably JWT <a id="ably-jwt" />
948948

949949
An Ably JWT is not strictly an Ably construct, rather it is a [JWT](https://jwt.io/) which has been constructed to be compatible with Ably. The JWT must adhere to the following to ensure compatibility:
950950

@@ -993,7 +993,7 @@ var ablyJwt = base64Header + "." + base64Claims + "." + signature;
993993

994994
<If lang="javascript,nodejs">
995995

996-
### BatchResult <a id="#batch-result" />
996+
### BatchResult <a id="batch-result" />
997997

998998
A `BatchResult` contains information about the results of a batch operation.
999999

@@ -1005,7 +1005,7 @@ A `BatchResult` contains information about the results of a batch operation.
10051005
| failureCount | The number of unsuccessful operations in the request | `Number` |
10061006
| messages | An array of results for the batch operation (for example, an array of [`BatchPublishSuccessResult`](/docs/api/realtime-sdk/types#batch-publish-success-result) or [`BatchPublishFailureResult`](/docs/api/realtime-sdk/types#batch-publish-failure-result) for a channel batch publish request) | `Object[]` |
10071007

1008-
### TokenRevocationTargetSpecifier <a id="#token-revocation-target-specifier" />
1008+
### TokenRevocationTargetSpecifier <a id="token-revocation-target-specifier" />
10091009

10101010
A `TokenRevocationTargetSpecifier` describes which tokens should be affected by a token revocation request.
10111011

@@ -1016,7 +1016,7 @@ A `TokenRevocationTargetSpecifier` describes which tokens should be affected by
10161016
| type | The type of token revocation target specifier. Valid values include `clientId`, `revocationKey` and `channel` | `String` |
10171017
| value | The value of the token revocation target specifier | `String` |
10181018

1019-
### TokenRevocationOptions <a id="#token-revocation-options" />
1019+
### TokenRevocationOptions <a id="token-revocation-options" />
10201020

10211021
A `TokenRevocationOptions` describes the additional options accepted by revoke tokens request.
10221022

@@ -1028,7 +1028,7 @@ A `TokenRevocationOptions` describes the additional options accepted by revoke t
10281028
| allowReauthMargin | _false_ If true, permits a token renewal cycle to take place without needing established connections to be dropped, by postponing enforcement to 30 seconds in the future, and sending any existing connections a hint to obtain (and upgrade the connection to use) a new token. The default is `false`, meaning that the effect is near-immediate. | `Boolean` |
10291029

10301030

1031-
### TokenRevocationSuccessResult <a id="#token-revocation-success-result" />
1031+
### TokenRevocationSuccessResult <a id="token-revocation-success-result" />
10321032

10331033
A `TokenRevocationSuccessResult` contains information about the result of a successful token revocation request for a single target specifier.
10341034

@@ -1040,7 +1040,7 @@ A `TokenRevocationSuccessResult` contains information about the result of a succ
10401040
| appliesAt | The time at which the token revocation will take effect, as a Unix timestamp in milliseconds | `Number` |
10411041
| issuedBefore | A Unix timestamp in milliseconds. Only tokens issued earlier than this time will be revoked | `Number` |
10421042

1043-
### TokenRevocationFailureResult <a id="#token-revocation-failure-result" />
1043+
### TokenRevocationFailureResult <a id="token-revocation-failure-result" />
10441044

10451045
A `TokenRevocationFailureResult` contains information about the result of an unsuccessful token revocation request for a single target specifier.
10461046

0 commit comments

Comments
 (0)