Skip to content

Commit

Permalink
feat: add anon verify feature
Browse files Browse the repository at this point in the history
  • Loading branch information
beeman committed Jan 24, 2024
1 parent 94e26d3 commit 6d001ee
Show file tree
Hide file tree
Showing 41 changed files with 673 additions and 32 deletions.
6 changes: 4 additions & 2 deletions api-schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -255,16 +255,17 @@ type DiscordServerRole {
}

type Identity {
avatarUrl: String
challenges: [IdentityChallenge!]
createdAt: DateTime!
createdAt: DateTime
expired: Boolean
id: String!
name: String
owner: User
profile: JSON
provider: IdentityProvider!
providerId: String!
updatedAt: DateTime!
updatedAt: DateTime
url: String
verified: Boolean
}
Expand Down Expand Up @@ -443,6 +444,7 @@ type Query {
adminFindOneNetworkToken(networkTokenId: String!): NetworkToken
adminFindOneRule(ruleId: String!): Rule
adminFindOneUser(userId: String!): User
anonFindUserByIdentity(provider: IdentityProvider!, providerId: String!): User
anonRequestIdentityChallenge(input: RequestIdentityChallengeInput!): IdentityChallenge
appConfig: AppConfig!
me: User
Expand Down
36 changes: 29 additions & 7 deletions libs/api/identity/data-access/src/lib/api-anon-identity.service.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
import { Injectable, Logger } from '@nestjs/common'
import {
ApiCoreService,
BaseContext,
ellipsify,
getRequestDetails,
slugifyId,
} from '@pubkey-link/api-core-data-access'
import { ApiCoreService, BaseContext, ellipsify, getRequestDetails, slugifyId } from '@pubkey-link/api-core-data-access'
import { RequestIdentityChallengeInput } from './dto/request-identity-challenge.input'
import { VerifyIdentityChallengeInput } from './dto/verify-identity-challenge-input'
import { sha256 } from './helpers/sha256'
Expand All @@ -22,6 +16,34 @@ export class ApiAnonIdentityService {
private readonly solana: ApiSolanaIdentityService,
) {}

findUserByIdentity(provider: IdentityProvider, providerId: string) {
console.log('findUserByIdentity', { provider, providerId })
return this.core.data.user.findFirst({
where: {
identities: {
some: {
provider,
providerId,
},
},
status: UserStatus.Active,
},
select: {
avatarUrl: true,
developer: true,
id: true,
name: true,
role: true,
username: true,
status: true,
identities: {
orderBy: [{ provider: 'asc' }, { providerId: 'asc' }],
select: { id: true, name: true, profile: true, provider: true, providerId: true },
},
},
})
}

async requestIdentityChallenge(ctx: BaseContext, { provider, providerId }: RequestIdentityChallengeInput) {
// Make sure we can link the given provider
this.solana.ensureLinkProvider(provider)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ import { IdentityProvider } from './identity-provider.enum'
export class Identity {
@Field()
id!: string
@Field()
createdAt!: Date
@Field()
updatedAt!: Date
@Field({ nullable: true })
createdAt?: Date
@Field({ nullable: true })
updatedAt?: Date

@Field(() => IdentityProvider)
provider!: IdentityProvider
Expand Down
10 changes: 10 additions & 0 deletions libs/api/identity/feature/src/lib/api-anon-identity.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,24 @@ import { BaseContext } from '@pubkey-link/api-core-data-access'
import {
ApiIdentityService,
IdentityChallenge,
IdentityProvider,
RequestIdentityChallengeInput,
VerifyIdentityChallengeInput,
} from '@pubkey-link/api-identity-data-access'
import { User } from '@pubkey-link/api-user-data-access'

@Resolver()
export class ApiAnonIdentityResolver {
constructor(private readonly service: ApiIdentityService) {}

@Query(() => User, { nullable: true })
anonFindUserByIdentity(
@Args({ name: 'provider', type: () => IdentityProvider }) provider: IdentityProvider,
@Args('providerId') providerId: string,
) {
return this.service.anon.findUserByIdentity(provider, providerId)
}

@Query(() => IdentityChallenge, { nullable: true })
anonRequestIdentityChallenge(@Context() ctx: BaseContext, @Args('input') input: RequestIdentityChallengeInput) {
return this.service.anon.requestIdentityChallenge(ctx, input)
Expand Down
5 changes: 5 additions & 0 deletions libs/api/identity/feature/src/lib/api-identity.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import { getIdentityUrl, Identity } from '@pubkey-link/api-identity-data-access'

@Resolver(() => Identity)
export class ApiIdentityResolver {
@ResolveField(() => String, { nullable: true })
avatarUrl(@Parent() identity: Identity) {
return (identity.profile as { avatarUrl?: string })?.avatarUrl ?? null
}

@ResolveField(() => Boolean, { nullable: true })
expired(@Parent() identity: Identity) {
if (identity.provider !== IdentityProvider.Discord) return false
Expand Down
Loading

0 comments on commit 6d001ee

Please sign in to comment.