AuthorizeRequesterDetails.tsx 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import { OAuthScope } from '@supabase/shared-types/out/constants'
  2. import { Check } from 'lucide-react'
  3. import { PERMISSIONS_DESCRIPTIONS } from './OAuthApps.constants'
  4. export interface AuthorizeRequesterDetailsProps {
  5. icon: string | null
  6. name: string
  7. domain: string
  8. scopes: OAuthScope[]
  9. showOnlyScopes?: boolean
  10. }
  11. export const ScopeSection = ({
  12. description,
  13. hasReadScope,
  14. hasWriteScope,
  15. }: {
  16. description: string
  17. hasReadScope: boolean
  18. hasWriteScope: boolean
  19. }) => {
  20. if (hasReadScope || hasWriteScope) {
  21. const perms = [hasReadScope ? 'Read' : null, hasWriteScope ? 'Write' : null]
  22. .filter(Boolean)
  23. .map((str) => (
  24. <span key={str} className="font-semibold text-foreground">
  25. {str}
  26. </span>
  27. ))
  28. .reduce((acc, v) => (
  29. <>
  30. {acc}
  31. <span> and </span>
  32. {v}
  33. </>
  34. ))
  35. return (
  36. <div className="first:border-t border-b flex flex-row space-x-1 text-sm text-foreground-light py-2 px-1">
  37. <div className="pt-0.5">
  38. <Check stroke="green" height={18} width={18} strokeWidth={1.5} />
  39. </div>
  40. <div>
  41. {perms} {description}
  42. </div>
  43. </div>
  44. )
  45. }
  46. return null
  47. }
  48. export const AuthorizeRequesterDetails = ({
  49. icon,
  50. name,
  51. domain,
  52. scopes,
  53. showOnlyScopes = false,
  54. }: AuthorizeRequesterDetailsProps) => {
  55. return (
  56. <div className="flex gap-y-4 flex-col">
  57. {!showOnlyScopes && (
  58. <div className="flex flex-row gap-x-4 items-center">
  59. <div className="flex items-center">
  60. <div
  61. className="w-12 h-12 md:w-14 md:h-14 bg-center bg-no-repeat bg-cover flex items-center justify-center rounded-md border border-control"
  62. style={{
  63. backgroundImage: !!icon ? `url('${icon}')` : 'none',
  64. }}
  65. >
  66. {!icon && <p className="text-foreground-light text-lg">{name[0]}</p>}
  67. </div>
  68. </div>
  69. <p className="text-foreground">
  70. {name} ({domain}) is requesting API access to an organization.
  71. </p>
  72. </div>
  73. )}
  74. <div>
  75. {!showOnlyScopes && (
  76. <>
  77. <h3>Permissions</h3>
  78. <p className="text-sm text-foreground-light">
  79. The following scopes will apply for the{' '}
  80. <span className="text-amber-900">selected organization and all of its projects.</span>
  81. </p>
  82. </>
  83. )}
  84. <div className="pt-2">
  85. {scopes.length === 0 && (
  86. <p className="text-foreground-lighter text-sm">
  87. No permissions requested, {name} will not have access to your organization or projects
  88. </p>
  89. )}
  90. <ScopeSection
  91. description={PERMISSIONS_DESCRIPTIONS.ANALYTICS}
  92. hasReadScope={scopes.includes(OAuthScope.ANALYTICS_READ)}
  93. hasWriteScope={scopes.includes(OAuthScope.ANALYTICS_WRITE)}
  94. />
  95. <ScopeSection
  96. description={PERMISSIONS_DESCRIPTIONS.ANALYTICS_CONFIG}
  97. hasReadScope={scopes.includes(OAuthScope.ANALYTICS_CONFIG_READ)}
  98. hasWriteScope={scopes.includes(OAuthScope.ANALYTICS_CONFIG_WRITE)}
  99. />
  100. <ScopeSection
  101. description={PERMISSIONS_DESCRIPTIONS.AUTH}
  102. hasReadScope={scopes.includes(OAuthScope.AUTH_READ)}
  103. hasWriteScope={scopes.includes(OAuthScope.AUTH_WRITE)}
  104. />
  105. <ScopeSection
  106. description={PERMISSIONS_DESCRIPTIONS.DATABASE}
  107. hasReadScope={scopes.includes(OAuthScope.DATABASE_READ)}
  108. hasWriteScope={scopes.includes(OAuthScope.DATABASE_WRITE)}
  109. />
  110. <ScopeSection
  111. description={PERMISSIONS_DESCRIPTIONS.DOMAINS}
  112. hasReadScope={scopes.includes(OAuthScope.DOMAINS_READ)}
  113. hasWriteScope={scopes.includes(OAuthScope.DOMAINS_WRITE)}
  114. />
  115. <ScopeSection
  116. description={PERMISSIONS_DESCRIPTIONS.EDGE_FUNCTIONS}
  117. hasReadScope={scopes.includes(OAuthScope.EDGE_FUNCTIONS_READ)}
  118. hasWriteScope={scopes.includes(OAuthScope.EDGE_FUNCTIONS_WRITE)}
  119. />
  120. <ScopeSection
  121. description={PERMISSIONS_DESCRIPTIONS.ENVIRONMENT}
  122. hasReadScope={scopes.includes(OAuthScope.ENVIRONMENT_READ)}
  123. hasWriteScope={scopes.includes(OAuthScope.ENVIRONMENT_WRITE)}
  124. />
  125. <ScopeSection
  126. description={PERMISSIONS_DESCRIPTIONS.ORGANIZATIONS}
  127. hasReadScope={scopes.includes(OAuthScope.ORGANIZATIONS_READ)}
  128. hasWriteScope={scopes.includes(OAuthScope.ORGANIZATIONS_WRITE)}
  129. />
  130. <ScopeSection
  131. description={PERMISSIONS_DESCRIPTIONS.PROJECTS}
  132. hasReadScope={scopes.includes(OAuthScope.PROJECTS_READ)}
  133. hasWriteScope={scopes.includes(OAuthScope.PROJECTS_WRITE)}
  134. />
  135. <ScopeSection
  136. description={PERMISSIONS_DESCRIPTIONS.REST}
  137. hasReadScope={scopes.includes(OAuthScope.REST_READ)}
  138. hasWriteScope={scopes.includes(OAuthScope.REST_WRITE)}
  139. />
  140. <ScopeSection
  141. description={PERMISSIONS_DESCRIPTIONS.SECRETS}
  142. hasReadScope={scopes.includes(OAuthScope.SECRETS_READ)}
  143. hasWriteScope={scopes.includes(OAuthScope.SECRETS_WRITE)}
  144. />
  145. <ScopeSection
  146. description={PERMISSIONS_DESCRIPTIONS.STORAGE}
  147. hasReadScope={scopes.includes(OAuthScope.STORAGE_READ)}
  148. hasWriteScope={scopes.includes(OAuthScope.STORAGE_WRITE)}
  149. />
  150. </div>
  151. </div>
  152. </div>
  153. )
  154. }