Skip to content

Commit e530b87

Browse files
committed
🐛 implement Apple Login process
1 parent 47e791c commit e530b87

File tree

4 files changed

+26
-15
lines changed

4 files changed

+26
-15
lines changed

src/domain/user.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ export interface userLoginReq {
9090
aff_code?: string
9191
siteverify_code?: string
9292
id_token?: string
93+
client_id?: string
9394
}
9495

9596
export interface userLoginResp {
@@ -119,6 +120,13 @@ export class UserService {
119120
const req = await RequestUtils.json<userLoginReq>(request)
120121
const authRes = await new SlaxAuth(ctx.env).login(req)
121122

123+
if (req.type === 'apple' && authRes.sub && authRes.email.endsWith('@appleid.apple.com')) {
124+
const platformBind = await this.userRepo.getUserByPlatform('apple', authRes.sub)
125+
if (platformBind && platformBind.user_name) {
126+
authRes.email = platformBind.user_name
127+
}
128+
}
129+
122130
// get user info by email
123131
const findRes = await this.userRepo.getInfoByEmail(authRes.email)
124132
if (findRes instanceof Error) {
@@ -152,6 +160,10 @@ export class UserService {
152160
const signUserId = new Hashid(ctx.env).encodeId(regInfo.id)
153161
const token = await new Auth(ctx.env).sign({ id: String(signUserId), lang: regInfo.lang, email: regInfo.email })
154162

163+
if (req.type === 'apple' && authRes.sub && authRes.email && !authRes.email.endsWith('@appleid.apple.com')) {
164+
await this.userRepo.userBindPlatform(regInfo.id, platformBindType.APPLE, authRes.sub, authRes.email)
165+
}
166+
155167
// 发放邀请奖励
156168
// if (isFirstRegister && req.aff_code) {
157169
// const turnstileToken = req.siteverify_code

src/infra/repository/dbUser.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ export enum platformBindType {
3535
TELEGRAM = 'telegram',
3636
WECHAT = 'wechat',
3737
QQ = 'qq',
38-
EMAIL = 'email'
38+
EMAIL = 'email',
39+
APPLE = 'apple'
3940
}
4041

4142
export enum noticeType {

src/utils/auth.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ export class SlaxAuth {
4949
}
5050

5151
public async loginWithApple(req: userLoginReq): Promise<SlaxAuthResult> {
52-
const res = await new AppleAuth(this.env).loginWithApple(req.code, req.id_token || '', req.redirect_uri)
52+
const res = await new AppleAuth(this.env).loginWithApple(req.code, req.id_token || '', req.client_id || '', req.redirect_uri)
5353
console.log('loginWithApple result:', res)
5454

55-
const userName = !!req.family_name ? `${req.given_name} ${req.family_name}` : undefined
56-
const givenName = req.given_name || undefined
57-
const familyName = req.family_name || undefined
58-
const email = `${res.sub}@appleid.apple.com`
55+
const givenName = req.given_name || ''
56+
const familyName = req.family_name || ''
57+
const userName = familyName ? `${givenName} ${familyName}`.trim() : givenName || ''
58+
const email = res.email || `${res.sub}@appleid.apple.com`
5959

6060
return {
6161
iss: res.iss,

src/utils/authLogin/authApple.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ export interface AppleKey {
4040
export class AppleAuth {
4141
private kv: KVNamespace
4242
private keyId: string
43-
private clientId: string
4443
private teamId: string
4544
private privateKey: string
4645

@@ -53,7 +52,6 @@ export class AppleAuth {
5352
this.kv = env.KV
5453
this.keyId = env.APPLE_SIGN_KEY_ID
5554
this.privateKey = env.APPLE_SIGN_AUTH_KEY
56-
this.clientId = env.APPLE_SIGN_CLIENT_ID
5755
this.teamId = env.APPLE_SIGN_TEAM_ID
5856
this.privateKey = this.privateKey
5957
.replace(/\\n/g, '')
@@ -63,7 +61,7 @@ export class AppleAuth {
6361
}
6462

6563
//  get client secret
66-
private async getClientSecret(): Promise<string> {
64+
private async getClientSecret(clientId: string): Promise<string> {
6765
const header = { alg: AppleAuth.algorithm, kid: this.keyId }
6866
const privateKey = await importPKCS8(this.privateKey, 'ES256')
6967

@@ -72,17 +70,17 @@ export class AppleAuth {
7270
.setIssuer(this.teamId)
7371
.setExpirationTime('170days')
7472
.setIssuedAt()
75-
.setSubject(this.clientId)
73+
.setSubject(clientId)
7674
.setAudience(AppleAuth.ENDPOINT_URL)
7775
.sign(privateKey)
7876
}
7977

80-
private async getAuthorizationToken(code: string, clientSecret: string, redirectUri?: string): Promise<AppleAuthorizationTokenResponseType> {
78+
private async getAuthorizationToken(code: string, clientId: string, clientSecret: string, redirectUri?: string): Promise<AppleAuthorizationTokenResponseType> {
8179
const url = new URL(AppleAuth.ENDPOINT_URL)
8280
url.pathname = '/auth/token'
8381

8482
const params = new URLSearchParams()
85-
params.append('client_id', this.clientId)
83+
params.append('client_id', clientId)
8684
params.append('client_secret', clientSecret)
8785
params.append('code', code)
8886
params.append('grant_type', 'authorization_code')
@@ -114,11 +112,11 @@ export class AppleAuth {
114112
}
115113

116114
//  Sign in with Apple
117-
async loginWithApple(code: string, idToken: string, redirectUri?: string): Promise<AppleIdTokenType> {
115+
async loginWithApple(code: string, idToken: string, clientId: string, redirectUri?: string): Promise<AppleIdTokenType> {
118116
try {
119-
const clientRes = await this.getClientSecret()
117+
const clientRes = await this.getClientSecret(clientId)
120118

121-
const tokenResp = await this.getAuthorizationToken(code, clientRes, redirectUri)
119+
const tokenResp = await this.getAuthorizationToken(code, clientId, clientRes, redirectUri)
122120

123121
const authResp = await this.verifyIdToken(tokenResp.id_token)
124122

0 commit comments

Comments
 (0)