@auth-craft/client 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -263,11 +263,14 @@ await client.oauth.start('google') // leaves for the provider; rememb
|
|
|
263
263
|
|
|
264
264
|
// on the page the provider returns to
|
|
265
265
|
const done = await client.oauth.finish() // reads ?code&state
|
|
266
|
-
if (!done.ok) return showError(done.errors)
|
|
266
|
+
if (!done.ok) return showError(done.errors) // done.meta?.params?.returnTo: the page to offer going back to
|
|
267
|
+
if (done.data.status === 'cancelled') return location.assign(done.data.returnTo)
|
|
267
268
|
if ('requiresMfa' in done.data.login) return askForCode(done.data.login.mfa)
|
|
268
269
|
location.assign(done.data.returnTo) // always a path on this site
|
|
269
270
|
```
|
|
270
271
|
|
|
272
|
+
`status` is `'cancelled'` when the visitor declined at the provider (`error=access_denied`), and `'completed'` when the provider step finished: `login` holds tokens or a further step. Any other provider error is `OAUTH_PROVIDER_ERROR`.
|
|
273
|
+
|
|
271
274
|
### `users`
|
|
272
275
|
`updateProfile({ body })`
|
|
273
276
|
|
|
@@ -39,12 +39,25 @@ export interface OAuthFinishOptions {
|
|
|
39
39
|
/** Needed only if the page has no storage left from `start`. */
|
|
40
40
|
provider?: string;
|
|
41
41
|
}
|
|
42
|
-
|
|
42
|
+
/**
|
|
43
|
+
* A visitor who declined at the provider is not a failure, so it is a `status` and not
|
|
44
|
+
* an error. `completed` says only that the provider step finished: `login` may still
|
|
45
|
+
* be a further step.
|
|
46
|
+
*
|
|
47
|
+
* Failures after the provider sent the visitor back carry the same path in
|
|
48
|
+
* `meta.params.returnTo`.
|
|
49
|
+
*/
|
|
50
|
+
export type OAuthFinish<TLogin> = {
|
|
51
|
+
status: 'completed';
|
|
43
52
|
/** Tokens, or a further step: check `requiresMfa` / `requiresChallenge` as for any login. */
|
|
44
53
|
login: TLogin;
|
|
45
54
|
/** A path on this site, safe to navigate to. */
|
|
46
55
|
returnTo: string;
|
|
47
|
-
}
|
|
56
|
+
} | {
|
|
57
|
+
status: 'cancelled';
|
|
58
|
+
/** A path on this site, safe to navigate to. */
|
|
59
|
+
returnTo: string;
|
|
60
|
+
};
|
|
48
61
|
export type OAuthClient<G> = G extends OAuthEndpoints<infer TLogin> ? G & {
|
|
49
62
|
start(provider: string, options?: OAuthStartOptions): Promise<Result<void>>;
|
|
50
63
|
finish(params?: URLSearchParams | string, options?: OAuthFinishOptions): Promise<Result<OAuthFinish<TLogin>>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-flow.d.ts","sourceRoot":"","sources":["../../src/core/oauth-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAIvD;;;GAGG;AACH,MAAM,WAAW,cAAc,CAAC,MAAM;IACpC,UAAU,CAAC,GAAG,EAAE;QAAE,IAAI,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAAE,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC/F,aAAa,CAAC,GAAG,EAAE;QACjB,IAAI,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC5E,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,
|
|
1
|
+
{"version":3,"file":"oauth-flow.d.ts","sourceRoot":"","sources":["../../src/core/oauth-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAIvD;;;GAGG;AACH,MAAM,WAAW,cAAc,CAAC,MAAM;IACpC,UAAU,CAAC,GAAG,EAAE;QAAE,IAAI,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAAE,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAC/F,aAAa,CAAC,GAAG,EAAE;QACjB,IAAI,EAAE;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KAC5E,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,yDAAyD;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gEAAgE;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,CAAC,MAAM,IAC1B;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,6FAA6F;IAC7F,KAAK,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;CAClB,GACD;IACE,MAAM,EAAE,WAAW,CAAC;IACpB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEN,MAAM,MAAM,WAAW,CAAC,CAAC,IACvB,CAAC,SAAS,cAAc,CAAC,MAAM,MAAM,CAAC,GAClC,CAAC,GAAG;IACF,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5E,MAAM,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;CAC/G,GACD,KAAK,CAAC;AAEZ;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CASrF;AAoBD,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,MAAM,EAAE,CAAC,SAAS,cAAc,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,CA6ChG"}
|
package/dist/core/oauth-flow.js
CHANGED
|
@@ -58,22 +58,25 @@ export function withOAuthFlow(group) {
|
|
|
58
58
|
async finish(params = window.location.search, options) {
|
|
59
59
|
const query = typeof params === 'string' ? new URLSearchParams(params) : params;
|
|
60
60
|
const stored = recall();
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
const returnTo = safeReturnTo(typeof stored.returnTo === 'string' ? stored.returnTo : '/', window.location.origin);
|
|
62
|
+
const providerError = query.get('error');
|
|
63
|
+
if (providerError === 'access_denied')
|
|
64
|
+
return ok({ status: 'cancelled', returnTo });
|
|
65
|
+
if (providerError) {
|
|
66
|
+
return err({ code: 'OAUTH_PROVIDER_ERROR', message: 'The provider did not complete the sign-in' }, { params: { returnTo } });
|
|
63
67
|
}
|
|
64
68
|
const code = query.get('code');
|
|
65
69
|
const state = query.get('state');
|
|
66
70
|
const provider = options?.provider ?? (typeof stored.provider === 'string' ? stored.provider : undefined);
|
|
67
71
|
if (!code || !state || !provider) {
|
|
68
|
-
return err({ code: 'OAUTH_CALLBACK_INVALID', message: 'This page was not opened by a provider sign-in' });
|
|
72
|
+
return err({ code: 'OAUTH_CALLBACK_INVALID', message: 'This page was not opened by a provider sign-in' }, { params: { returnTo } });
|
|
69
73
|
}
|
|
70
74
|
const login = await group.oauthCallback({
|
|
71
75
|
body: { provider, code, state, ...(options?.tenantId !== undefined && { tenantId: options.tenantId }) },
|
|
72
76
|
});
|
|
73
77
|
if (!login.ok)
|
|
74
|
-
return err(login.errors, login.meta);
|
|
75
|
-
|
|
76
|
-
return ok({ login: login.data, returnTo });
|
|
78
|
+
return err(login.errors, { ...login.meta, params: { ...login.meta?.params, returnTo } });
|
|
79
|
+
return ok({ status: 'completed', login: login.data, returnTo });
|
|
77
80
|
},
|
|
78
81
|
};
|
|
79
82
|
return { ...group, ...flow };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-flow.js","sourceRoot":"","sources":["../../src/core/oauth-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,GAAG,EAAE,EAAE,EAAe,MAAM,iBAAiB,CAAC;AAEvD,MAAM,WAAW,GAAG,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"oauth-flow.js","sourceRoot":"","sources":["../../src/core/oauth-flow.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@auth-craft/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Contract-driven typed frontend client for Auth Craft. Methods are generated from @auth-craft/api-contract; tokens are isolated in a Web Worker. Import the root for all groups, or @auth-craft/client/core for a scope-agnostic core you wire per scope.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|