@gasboost/auth 0.8.0 → 0.9.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 +49 -25
- package/dist/AppsScriptAuth.d.ts +2 -0
- package/dist/AppsScriptAuth.js +8 -1
- package/dist/api/AppsScriptAuthAccount.d.ts +23 -0
- package/dist/api/AppsScriptAuthAccount.js +50 -0
- package/dist/api/AppsScriptAuthRegistration.d.ts +1 -13
- package/dist/api/AppsScriptAuthRegistration.js +2 -78
- package/dist/api/AppsScriptAuthSignUp.d.ts +1 -1
- package/dist/api/AppsScriptAuthSignUp.js +5 -2
- package/dist/index.d.ts +1 -0
- package/dist/registration/AppsScriptRegistration.d.ts +2 -2
- package/dist/registration/AppsScriptRegistration.js +4 -8
- package/dist/storage/AppsScriptAuthRepository.d.ts +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -281,12 +281,13 @@ const user = await auth.registration.email({
|
|
|
281
281
|
```ts
|
|
282
282
|
const user = await auth.registration.appsScript({
|
|
283
283
|
name: "Taro",
|
|
284
|
+
email: "taro@example.com",
|
|
284
285
|
});
|
|
285
286
|
```
|
|
286
287
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
288
|
+
Registration は指定された対象者の新規 User と最初の Account を作成します。
|
|
289
|
+
Session は参照しません。同じ provider / email の重複は拒否し、
|
|
290
|
+
別方式の User とメールが一致しても自動統合しません。
|
|
290
291
|
|
|
291
292
|
### Sign Upとの違い
|
|
292
293
|
|
|
@@ -692,32 +693,55 @@ const auth = new AppsScriptAuth({
|
|
|
692
693
|
|
|
693
694
|
MIT
|
|
694
695
|
|
|
695
|
-
|
|
696
|
+
## 既存 User への Account 追加(0.9.0)
|
|
696
697
|
|
|
697
698
|
`registration.methods` は設定の `enabled` を返します。
|
|
698
|
-
`
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
699
|
+
`auth.account.add(userId, input)` は明示した既存 User に Account を追加して返します。
|
|
700
|
+
新規 User や Session は作成せず、`isSignupEnabled` に依存しません。
|
|
701
|
+
同一 Identity の重複、他 User の Identity、同じ User の同一方式の追加は拒否します。
|
|
702
|
+
対象の認証方式は `enabled: true` が必要です。
|
|
702
703
|
|
|
703
704
|
```ts
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
705
|
+
// 呼び出し元で初期化権限・実行主体を検証した後に実行
|
|
706
|
+
const email = Session.getEffectiveUser().getEmail();
|
|
707
|
+
const user = auth.registration.methods.appsScript
|
|
708
|
+
? await auth.registration.appsScript({ name: "システム管理者", email })
|
|
709
|
+
: await auth.registration.email({
|
|
710
|
+
name: "システム管理者",
|
|
711
|
+
email,
|
|
712
|
+
password: temporaryPassword,
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
if (
|
|
716
|
+
auth.registration.methods.appsScript &&
|
|
717
|
+
auth.registration.methods.emailPassword
|
|
718
|
+
) {
|
|
719
|
+
await auth.account.add(user.id, {
|
|
720
|
+
provider: "emailPassword",
|
|
721
|
+
email,
|
|
722
|
+
password: temporaryPassword,
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
// Apps Script Account を既存 User に追加する場合:
|
|
726
|
+
// await auth.account.add(userId, { provider: "appsScript", email });
|
|
712
727
|
```
|
|
713
728
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
729
|
+
メールとパスワードの Account は新しい Account ID を salt としてパスワードをハッシュ化します。
|
|
730
|
+
既存 Account や User 名は変更しません。
|
|
731
|
+
呼び出し元で対象 User への追加権限を検証してください。
|
|
732
|
+
`@gasboost/auth-app` の `handlers(auth)` はこの管理用 API を RPC に公開しません。
|
|
733
|
+
公開 `signUp.appsScript({ name })` は引き続き ActiveUser を登録し、Session を発行します。
|
|
734
|
+
|
|
735
|
+
### Repository と移行
|
|
736
|
+
|
|
737
|
+
0.9.0 では `registration.appsScript({ name })` を `{ name, email }` に変更しました。
|
|
738
|
+
0.8.0 の `registration.ensure()` と任意の `repository.user.save()` は削除しました。
|
|
739
|
+
旧 PR の EffectiveUser 専用登録経路も提供しません。
|
|
740
|
+
通常の `registration.email()` と公開 SignUp の契約は維持します。
|
|
718
741
|
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
742
|
+
Account 追加には任意の Repository メソッド `account.create(account): Promise<Account>` が必要です。
|
|
743
|
+
未対応の Repository は既存 API を継続利用でき、`account.add` 呼び出し時にエラーになります。
|
|
744
|
+
実装は存在する User への追加だけを許可し、Account ID・Identity・User ごとの同一方式の重複を
|
|
745
|
+
保存と同じ transaction 内で再検証してください。`@gasboost/auth-sheetorm >=0.4.1` が対応します。
|
|
746
|
+
複数 API にまたがる初期化の排他制御、途中失敗時の保存済み User ID の復旧や
|
|
747
|
+
再開処理は呼び出し元(Bootstrap 等)の責務です。
|
package/dist/AppsScriptAuth.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AppsScriptAuthAccount } from "./api/AppsScriptAuthAccount";
|
|
1
2
|
import { AppsScriptAuthPassword } from "./api/AppsScriptAuthPassword";
|
|
2
3
|
import { AppsScriptAuthRegistration } from "./api/AppsScriptAuthRegistration";
|
|
3
4
|
import { AppsScriptAuthSession } from "./api/AppsScriptAuthSession";
|
|
@@ -37,6 +38,7 @@ export declare class AppsScriptAuth<TEmailPassword extends EmailPasswordAuthOpti
|
|
|
37
38
|
readonly signOut: AppsScriptAuthSignOut;
|
|
38
39
|
readonly password: AppsScriptAuthPasswordApi<TEmailPassword>;
|
|
39
40
|
readonly registration: AppsScriptAuthRegistration;
|
|
41
|
+
readonly account: AppsScriptAuthAccount;
|
|
40
42
|
constructor({ repository, session, runtime, emailPassword, appsScript, hooks, }: AppsScriptAuthConfig<TEmailPassword, THookResult>);
|
|
41
43
|
}
|
|
42
44
|
export {};
|
package/dist/AppsScriptAuth.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AppsScriptAuth = void 0;
|
|
4
|
+
const AppsScriptAuthAccount_1 = require("./api/AppsScriptAuthAccount");
|
|
4
5
|
const AppsScriptAuthPassword_1 = require("./api/AppsScriptAuthPassword");
|
|
5
6
|
const AppsScriptAuthRegistration_1 = require("./api/AppsScriptAuthRegistration");
|
|
6
7
|
const AppsScriptAuthSession_1 = require("./api/AppsScriptAuthSession");
|
|
@@ -17,6 +18,7 @@ class AppsScriptAuth {
|
|
|
17
18
|
signOut;
|
|
18
19
|
password;
|
|
19
20
|
registration;
|
|
21
|
+
account;
|
|
20
22
|
constructor({ repository, session, runtime, emailPassword, appsScript, hooks, }) {
|
|
21
23
|
const sessionStorage = (0, sessionStorageFactory_1.sessionStorageFactory)(session.storageType, {
|
|
22
24
|
cacheService: runtime.cacheService,
|
|
@@ -64,12 +66,17 @@ class AppsScriptAuth {
|
|
|
64
66
|
emailPassword: emailPasswordConfig,
|
|
65
67
|
})
|
|
66
68
|
: undefined);
|
|
69
|
+
this.account = new AppsScriptAuthAccount_1.AppsScriptAuthAccount({
|
|
70
|
+
emailPassword: emailPasswordConfig,
|
|
71
|
+
appsScript: appsScriptConfig,
|
|
72
|
+
repository,
|
|
73
|
+
utilities: runtime.utilities,
|
|
74
|
+
});
|
|
67
75
|
this.registration = new AppsScriptAuthRegistration_1.AppsScriptAuthRegistration({
|
|
68
76
|
emailPassword: emailPasswordConfig,
|
|
69
77
|
appsScript: appsScriptConfig,
|
|
70
78
|
repository,
|
|
71
79
|
utilities: runtime.utilities,
|
|
72
|
-
session: runtime.session,
|
|
73
80
|
});
|
|
74
81
|
}
|
|
75
82
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AppsScriptAuthenticationConfig } from "../authentication/AppsScriptAuthentication";
|
|
2
|
+
import type { EmailPasswordAuthConfig } from "../authentication/EmailPasswordAuthentication";
|
|
3
|
+
import { Account } from "../domain/Account";
|
|
4
|
+
import type { AppsScriptAuthRepository } from "../storage/AppsScriptAuthRepository";
|
|
5
|
+
export type AddAccountInput = {
|
|
6
|
+
provider: "appsScript";
|
|
7
|
+
email: string;
|
|
8
|
+
} | {
|
|
9
|
+
provider: "emailPassword";
|
|
10
|
+
email: string;
|
|
11
|
+
password: string;
|
|
12
|
+
};
|
|
13
|
+
/** Server API. The caller must authorize account linking to the specified user. */
|
|
14
|
+
export declare class AppsScriptAuthAccount {
|
|
15
|
+
private readonly config;
|
|
16
|
+
constructor(config: {
|
|
17
|
+
repository: AppsScriptAuthRepository;
|
|
18
|
+
utilities: GoogleAppsScript.Utilities.Utilities;
|
|
19
|
+
emailPassword?: EmailPasswordAuthConfig;
|
|
20
|
+
appsScript?: AppsScriptAuthenticationConfig;
|
|
21
|
+
});
|
|
22
|
+
add(userId: string, input: AddAccountInput): Promise<Account>;
|
|
23
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AppsScriptAuthAccount = void 0;
|
|
4
|
+
const AuthPattern_1 = require("../AuthPattern");
|
|
5
|
+
const Account_1 = require("../domain/Account");
|
|
6
|
+
const Password_1 = require("../domain/Password");
|
|
7
|
+
const AppsScriptIdentity_1 = require("../identity/AppsScriptIdentity");
|
|
8
|
+
const EmailPasswordIdentity_1 = require("../identity/EmailPasswordIdentity");
|
|
9
|
+
/** Server API. The caller must authorize account linking to the specified user. */
|
|
10
|
+
class AppsScriptAuthAccount {
|
|
11
|
+
config;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
}
|
|
15
|
+
async add(userId, input) {
|
|
16
|
+
const { repository, utilities, emailPassword, appsScript } = this.config;
|
|
17
|
+
if (!userId?.trim() || !input.email?.trim())
|
|
18
|
+
throw new Error("User ID and email are required");
|
|
19
|
+
switch (input.provider) {
|
|
20
|
+
case AuthPattern_1.authPattern.emailPassword:
|
|
21
|
+
if (!emailPassword?.enabled)
|
|
22
|
+
throw new Error("Email and password authentication is disabled");
|
|
23
|
+
break;
|
|
24
|
+
case AuthPattern_1.authPattern.appsScript:
|
|
25
|
+
if (!appsScript?.enabled)
|
|
26
|
+
throw new Error("Apps Script authentication is disabled");
|
|
27
|
+
break;
|
|
28
|
+
default:
|
|
29
|
+
throw new Error("Unsupported auth provider");
|
|
30
|
+
}
|
|
31
|
+
if (!repository.account.create)
|
|
32
|
+
throw new Error("Repository must support account.create");
|
|
33
|
+
const user = await repository.user.find(userId);
|
|
34
|
+
if (!user || user.id !== userId)
|
|
35
|
+
throw new Error("User not found");
|
|
36
|
+
if (user.account(input.provider))
|
|
37
|
+
throw new Error("User already has an account for this provider");
|
|
38
|
+
if (await repository.account.findByIdentity(input.provider, input.email))
|
|
39
|
+
throw new Error("Account already registered");
|
|
40
|
+
const id = utilities.getUuid();
|
|
41
|
+
const identity = input.provider === AuthPattern_1.authPattern.emailPassword
|
|
42
|
+
? new EmailPasswordIdentity_1.EmailPasswordIdentity({
|
|
43
|
+
accountId: input.email,
|
|
44
|
+
password: await new Password_1.Password(input.password, utilities, emailPassword.pepper, emailPassword.iterations).hash(id),
|
|
45
|
+
})
|
|
46
|
+
: new AppsScriptIdentity_1.AppsScriptIdentity({ googleAccountAddress: input.email });
|
|
47
|
+
return repository.account.create(new Account_1.Account({ id, userId, identity }));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
exports.AppsScriptAuthAccount = AppsScriptAuthAccount;
|
|
@@ -11,24 +11,12 @@ export declare class AppsScriptAuthRegistration {
|
|
|
11
11
|
readonly emailPassword: boolean;
|
|
12
12
|
readonly appsScript: boolean;
|
|
13
13
|
};
|
|
14
|
-
|
|
15
|
-
private readonly utilities;
|
|
16
|
-
private readonly session;
|
|
17
|
-
private readonly emailPassword?;
|
|
18
|
-
constructor({ emailPassword, appsScript, repository, utilities, session, }: {
|
|
14
|
+
constructor({ emailPassword, appsScript, repository, utilities, }: {
|
|
19
15
|
emailPassword?: EmailPasswordAuthConfig;
|
|
20
16
|
appsScript?: AppsScriptAuthenticationConfig;
|
|
21
17
|
repository: AppsScriptAuthRepository;
|
|
22
18
|
utilities: GoogleAppsScript.Utilities.Utilities;
|
|
23
|
-
session: GoogleAppsScript.Base.Session;
|
|
24
19
|
});
|
|
25
20
|
email(input: EmailPasswordRegistrationInput): Promise<User>;
|
|
26
21
|
appsScript(input: AppsScriptRegistrationInput): Promise<User>;
|
|
27
|
-
/** Privileged server API. Caller must authorize and serialize provisioning. */
|
|
28
|
-
ensure(input: {
|
|
29
|
-
id: string;
|
|
30
|
-
name: string;
|
|
31
|
-
email: string;
|
|
32
|
-
password?: string;
|
|
33
|
-
}): Promise<User>;
|
|
34
22
|
}
|
|
@@ -1,27 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AppsScriptAuthRegistration = void 0;
|
|
4
|
-
const User_1 = require("../domain/User");
|
|
5
|
-
const Account_1 = require("../domain/Account");
|
|
6
|
-
const Password_1 = require("../domain/Password");
|
|
7
|
-
const AuthPattern_1 = require("../AuthPattern");
|
|
8
|
-
const AppsScriptIdentity_1 = require("../identity/AppsScriptIdentity");
|
|
9
|
-
const EmailPasswordIdentity_1 = require("../identity/EmailPasswordIdentity");
|
|
10
4
|
const AppsScriptRegistration_1 = require("../registration/AppsScriptRegistration");
|
|
11
5
|
const EmailPasswordRegistration_1 = require("../registration/EmailPasswordRegistration");
|
|
12
6
|
class AppsScriptAuthRegistration {
|
|
13
7
|
emailPasswordRegistration;
|
|
14
8
|
appsScriptRegistration;
|
|
15
9
|
methods;
|
|
16
|
-
repository
|
|
17
|
-
utilities;
|
|
18
|
-
session;
|
|
19
|
-
emailPassword;
|
|
20
|
-
constructor({ emailPassword, appsScript, repository, utilities, session, }) {
|
|
21
|
-
this.repository = repository;
|
|
22
|
-
this.utilities = utilities;
|
|
23
|
-
this.session = session;
|
|
24
|
-
this.emailPassword = emailPassword;
|
|
10
|
+
constructor({ emailPassword, appsScript, repository, utilities, }) {
|
|
25
11
|
this.methods = Object.freeze({
|
|
26
12
|
emailPassword: !!emailPassword?.enabled,
|
|
27
13
|
appsScript: !!appsScript?.enabled,
|
|
@@ -30,7 +16,7 @@ class AppsScriptAuthRegistration {
|
|
|
30
16
|
this.emailPasswordRegistration = new EmailPasswordRegistration_1.EmailPasswordRegistration(repository, utilities, emailPassword);
|
|
31
17
|
}
|
|
32
18
|
if (appsScript?.enabled) {
|
|
33
|
-
this.appsScriptRegistration = new AppsScriptRegistration_1.AppsScriptRegistration(utilities,
|
|
19
|
+
this.appsScriptRegistration = new AppsScriptRegistration_1.AppsScriptRegistration(utilities, repository);
|
|
34
20
|
}
|
|
35
21
|
}
|
|
36
22
|
async email(input) {
|
|
@@ -45,67 +31,5 @@ class AppsScriptAuthRegistration {
|
|
|
45
31
|
}
|
|
46
32
|
return this.appsScriptRegistration.register(input);
|
|
47
33
|
}
|
|
48
|
-
/** Privileged server API. Caller must authorize and serialize provisioning. */
|
|
49
|
-
async ensure(input) {
|
|
50
|
-
if (!this.methods.emailPassword && !this.methods.appsScript) {
|
|
51
|
-
throw new Error("No authentication method is enabled");
|
|
52
|
-
}
|
|
53
|
-
if (!input.id || !input.email.trim())
|
|
54
|
-
throw new Error("User ID and email are required");
|
|
55
|
-
if (!this.repository.user.save)
|
|
56
|
-
throw new Error("Repository must support idempotent user.save");
|
|
57
|
-
if (this.methods.appsScript &&
|
|
58
|
-
this.session.getActiveUser().getEmail() !== input.email) {
|
|
59
|
-
throw new Error("Active user does not match registration email");
|
|
60
|
-
}
|
|
61
|
-
const existing = await this.repository.user.find(input.id);
|
|
62
|
-
const accounts = [...(existing?.accounts ?? [])];
|
|
63
|
-
for (const provider of [
|
|
64
|
-
AuthPattern_1.authPattern.emailPassword,
|
|
65
|
-
AuthPattern_1.authPattern.appsScript,
|
|
66
|
-
]) {
|
|
67
|
-
if (provider === AuthPattern_1.authPattern.emailPassword
|
|
68
|
-
? !this.methods.emailPassword
|
|
69
|
-
: !this.methods.appsScript)
|
|
70
|
-
continue;
|
|
71
|
-
const collision = await this.repository.account.findByIdentity(provider, input.email);
|
|
72
|
-
if (collision && collision.userId !== input.id)
|
|
73
|
-
throw new Error("Account belongs to another user");
|
|
74
|
-
const current = accounts.find((account) => account.identity.providerName === provider);
|
|
75
|
-
if (current) {
|
|
76
|
-
if (current.userId !== input.id ||
|
|
77
|
-
current.identity.accountId !== input.email)
|
|
78
|
-
throw new Error("Existing user identity does not match");
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
if (collision) {
|
|
82
|
-
accounts.push(collision);
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
const accountId = `${input.id}:${provider}`;
|
|
86
|
-
let identity;
|
|
87
|
-
if (provider === AuthPattern_1.authPattern.emailPassword) {
|
|
88
|
-
if (!input.password || !this.emailPassword)
|
|
89
|
-
throw new Error("Password is required");
|
|
90
|
-
const password = new Password_1.Password(input.password, this.utilities, this.emailPassword.pepper, this.emailPassword.iterations);
|
|
91
|
-
identity = new EmailPasswordIdentity_1.EmailPasswordIdentity({
|
|
92
|
-
accountId: input.email,
|
|
93
|
-
password: await password.hash(accountId),
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
else {
|
|
97
|
-
identity = new AppsScriptIdentity_1.AppsScriptIdentity({
|
|
98
|
-
googleAccountAddress: input.email,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
accounts.push(new Account_1.Account({ id: accountId, userId: input.id, identity }));
|
|
102
|
-
}
|
|
103
|
-
const user = new User_1.User({
|
|
104
|
-
id: input.id,
|
|
105
|
-
name: existing?.name ?? input.name,
|
|
106
|
-
accounts,
|
|
107
|
-
});
|
|
108
|
-
return this.repository.user.save(user);
|
|
109
|
-
}
|
|
110
34
|
}
|
|
111
35
|
exports.AppsScriptAuthRegistration = AppsScriptAuthRegistration;
|
|
@@ -8,7 +8,7 @@ import type { AppsScriptSessionStorage } from "../storage/AppsScriptSessionStora
|
|
|
8
8
|
import { SignUp } from "./SignUp";
|
|
9
9
|
export declare class AppsScriptAuthSignUp<THookResult = undefined> {
|
|
10
10
|
email: SignUp<EmailPasswordRegistrationInput, THookResult>["execute"];
|
|
11
|
-
appsScript: SignUp<AppsScriptRegistrationInput, THookResult>["execute"];
|
|
11
|
+
appsScript: SignUp<Pick<AppsScriptRegistrationInput, "name">, THookResult>["execute"];
|
|
12
12
|
constructor({ sessionStorage, expiresIn, afterSignIn, repository, emailPassword, appsScript, utilities, session, }: {
|
|
13
13
|
sessionStorage: AppsScriptSessionStorage;
|
|
14
14
|
expiresIn: number;
|
|
@@ -27,14 +27,17 @@ class AppsScriptAuthSignUp {
|
|
|
27
27
|
throw new Error("Apps Script authentication is disabled");
|
|
28
28
|
}
|
|
29
29
|
appsScript.ensureSignUpEnabled();
|
|
30
|
+
const email = session.getActiveUser().getEmail();
|
|
31
|
+
if (!email)
|
|
32
|
+
throw new Error("No active user found");
|
|
30
33
|
const appsScriptSignUp = new SignUp_1.SignUp({
|
|
31
34
|
sessionStorage,
|
|
32
35
|
afterSignIn,
|
|
33
36
|
expiresIn,
|
|
34
|
-
registration: new AppsScriptRegistration_1.AppsScriptRegistration(utilities,
|
|
37
|
+
registration: new AppsScriptRegistration_1.AppsScriptRegistration(utilities, repository),
|
|
35
38
|
utilities,
|
|
36
39
|
});
|
|
37
|
-
return appsScriptSignUp.execute(input);
|
|
40
|
+
return appsScriptSignUp.execute({ name: input.name, email });
|
|
38
41
|
};
|
|
39
42
|
}
|
|
40
43
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,3 +16,4 @@ export { PasswordReset } from "./domain/PasswordReset";
|
|
|
16
16
|
export { AppsScriptIdentity } from "./identity/AppsScriptIdentity";
|
|
17
17
|
export { EmailPasswordIdentity } from "./identity/EmailPasswordIdentity";
|
|
18
18
|
export type { AfterSignInContext, AfterSignInHook, AuthHooks, } from "./hooks/AuthHooks";
|
|
19
|
+
export type { AddAccountInput } from "./api/AppsScriptAuthAccount";
|
|
@@ -3,11 +3,11 @@ import type { AppsScriptAuthRepository } from "../storage/AppsScriptAuthReposito
|
|
|
3
3
|
import type { Registration } from "./Registration";
|
|
4
4
|
export interface AppsScriptRegistrationInput {
|
|
5
5
|
readonly name: string;
|
|
6
|
+
readonly email: string;
|
|
6
7
|
}
|
|
7
8
|
export declare class AppsScriptRegistration implements Registration<AppsScriptRegistrationInput> {
|
|
8
9
|
private readonly utilities;
|
|
9
|
-
private readonly session;
|
|
10
10
|
private readonly repository;
|
|
11
|
-
constructor(utilities: GoogleAppsScript.Utilities.Utilities,
|
|
11
|
+
constructor(utilities: GoogleAppsScript.Utilities.Utilities, repository: AppsScriptAuthRepository);
|
|
12
12
|
register(input: AppsScriptRegistrationInput): Promise<User>;
|
|
13
13
|
}
|
|
@@ -7,19 +7,15 @@ const User_1 = require("../domain/User");
|
|
|
7
7
|
const AppsScriptIdentity_1 = require("../identity/AppsScriptIdentity");
|
|
8
8
|
class AppsScriptRegistration {
|
|
9
9
|
utilities;
|
|
10
|
-
session;
|
|
11
10
|
repository;
|
|
12
|
-
constructor(utilities,
|
|
11
|
+
constructor(utilities, repository) {
|
|
13
12
|
this.utilities = utilities;
|
|
14
|
-
this.session = session;
|
|
15
13
|
this.repository = repository;
|
|
16
14
|
}
|
|
17
15
|
async register(input) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
throw new Error("No active user found");
|
|
22
|
-
}
|
|
16
|
+
const email = input.email;
|
|
17
|
+
if (!email?.trim())
|
|
18
|
+
throw new Error("Email is required");
|
|
23
19
|
const existingAccount = await this.repository.account.findByIdentity(AuthPattern_1.authPattern.appsScript, email);
|
|
24
20
|
if (existingAccount) {
|
|
25
21
|
throw new Error("Account already registered");
|
|
@@ -4,13 +4,13 @@ import type { PasswordCredential } from "../domain/PasswordCredential";
|
|
|
4
4
|
import type { User } from "../domain/User";
|
|
5
5
|
export interface AppsScriptAuthRepository {
|
|
6
6
|
account: {
|
|
7
|
+
/** Create an account for an existing user. Reject identity, ID and provider duplicates atomically. */
|
|
8
|
+
create?: (account: Account) => Promise<Account>;
|
|
7
9
|
findByIdentity(provider: AuthPattern, identifier: string): Promise<Account | null>;
|
|
8
10
|
};
|
|
9
11
|
user: {
|
|
10
12
|
find: (id: string) => Promise<User | null>;
|
|
11
13
|
create: (user: User) => Promise<User>;
|
|
12
|
-
/** Upsert user/accounts by their stable IDs; retries must preserve a single user. */
|
|
13
|
-
save?: (user: User) => Promise<User>;
|
|
14
14
|
};
|
|
15
15
|
passwordCredential: {
|
|
16
16
|
findByResetTokenHash(tokenHash: string): Promise<PasswordCredential | null>;
|
package/package.json
CHANGED